This article describes how DevOps teams can quickly spin up a reliable, cost-effective Selenium grid for automated testing in minutes.
What Is Selenium & Selenium Grid?
If you've never heard of Selenium before, climb out from under that rock.
Selenium is a test automation framework that lets you script interactions against your web apps and run them in popular web browsers. Selenium Grid is a management service that coordinates the use of many instances of these browsers. You can point your Selenium scripts to a Grid, specify which "capabilities" (OS version, browser version, etc.) it would like in an interactive session, then drive actions in that browser session to verify functional correctness of a target app or website.
This is what it typically looks like in Selenium code:
Pretty simple, really, for what's really going on under all the layers of code and HTTP protocol communications.
Why Use a AWS for Your Selenium Grid
There are plenty of services that host Selenium-compliant grids, such as Sauce Labs and Browser Stack, and I recommend you consider one of the many SaaS options if you don't want to maintain and upgrade a grid on your own. However, if your team has reasonable automation skills and the human resources to do so, the benefit of a DIY grid is complete control for a fraction of the cost associated with hosted services.
Though I abhor the idea of paying hundreds of dollars per month for only a few parallel browser instances, a word of warning about DIY grids over SaaS alternatives:
- You don't get same-day support for the latest browsers and OS versions
- You don't benefit from script-to-driver version independence
- You don't get infinite scalability without some serious effort
- You don't get 24/7 operational oversight unless you pay someone to do it
If you (and your team) are okay with the above disclaimers and simply just want a quick, cheap way to spin up a grid, then the steps below suffice:
- Launch a Ubuntu linux distro to act as the Docker host.
I used an t2.xlarge at $0.19/hr to get 4vCPU variable and 16GB memory. Also set SDA storage to 32gb.
- Log in to your instance via SSH
- Switch to root account to install Docker with 'sudo su' command
- Install cAdvisor with this command:
sudo docker run \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:rw \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --volume=/dev/disk/:/dev/disk:ro \ --publish=8080:8080 \ --detach=true \ --name=cadvisor \ google/cadvisor:latest
- Install Selenium Hub:
$ docker network create grid $ docker run -d -p 4444:4444 --net grid --name selenium-hub selenium/hub:latest
- Create containers for your various browsers using debug versions and unique external port numbers (typically 5901, 5902, etc.):
$ docker run -d -P -p <port4VNC>:5900 --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-chrome-debug:latest $ docker run -d -P -p <port4VNC>:5900 --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm selenium/node-firefox-debug:latest
- In the security group you created/assigned during EC2 instance setup, add the following inbound rules:
4444 (Selenium Hub)
5900-6000 (VNC for various browsers)
- Verify that your grid contains the browsers you spun up:
- Connect to VNC remote services on instances using the ports assigned in the above docker run commands. On a Mac, I recommend VNC Viewer.
- Reference your grid in a Selenium script, using port 4444:
[picture of code]
Now when you run your script(s), particularly in parallel, you should see nodes on your grid running your automated script.
How Is a Selenium Grid Better Than Local Execution?
Well, for one, it's not popping up multiple browsers on your workstation while you're trying to get other work done. In build and continuous integration scenarios, you need to run automated Selenium scripts on an environment that doesn't include the laptops your developers take home with them at night.
You also want your test environment to be as versioned and reliable as possible, so having an on-demand grid that can be scripted as an AWS YAML descriptor and that meets your manual, on-demand, and CI testing requirements is a modern must.
Why Did I Write This Tutorial?
I'm a sometimes performance engineer. I needed a disposable Selenium Grid to show how to use a subset of browser sessions during a large load test to collect real-user experience metrics in NeoLoad. I didn't want to pay hundreds of dollars for a monthly subscription to something I could build in about 30mins.
Why am I running a subset of real browsers as part of a load test? That, my friends, is the really interesting part that I discuss in a later post.