Setting Up Your Own Selenium Grid on AWS

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:

  1. 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.
  2. Log in to your instance via SSH
  3. Switch to root account to install Docker with ‘sudo su’ command
  4. Install cAdvisor with this command:
  5. Install Selenium Hub:
  6. Create containers for your various browsers using debug versions and unique external port numbers (typically 5901, 5902, etc.):
  7. In the security group you created/assigned during EC2 instance setup, add the following inbound rules:
    7777 (cAdvisor)
    4444 (Selenium Hub)
    5900-6000 (VNC for various browsers)
  8. Verify that your grid contains the browsers you spun up:
    http://[host-ip]:7777/
  9. Connect to VNC remote services on instances using the ports assigned in the above docker run commands. On a Mac, I recommend VNC Viewer.
  10. 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.

Why responsive web developers must learn Selenium

Developers need fluency in technologies that the team uses for UI testing. Similarly, testing has become more a programmer’s job than a point-n-click task. As the world’s most widely-adopted web UI testing framework, Selenium is a must-know technology for responsive web development teams in order to maintain the pace of continuous delivery.

Mostly Working, Somewhat Broken ‘Builds’

I use the term ‘build’ loosely here when it comes to web apps, since it’s often more like packaging (particularly with Docker containers), but the idea is the same. You have code in a repo, that gets sucked in by your CI system, built/packaged), tested/validated, then deployed somewhere (temp stack or whatnot).

If the build succeeds but tests fail, you need to quickly assess if it’s the test’s fault or the new build. The only way to do that quickly is to maintain proficiency in technologies and practices used to validate the build.

Code in production is where money is made; broken code doesn’t make any money, it just makes people move on. Everyone is responsible for the result.

We have a QA person. That’s their job.

Not so fast. In continuous delivery teams, developers don’t have the luxury of leaving it to someone else. When build verification tests (BVT) fail, a developer needs to track down the source of the problem which typically means parsing the test failure logs, referring to the code and the context/data used for the test, then making some adjustment and re-running the tests.

Though your test engineer can fix the test, you still have to wait for a developer to fix problems in code. Why not make them the same person?

Of course I’m not suggesting that every developer write ALL their own UI/UX tests, there’s a division of labor and skills match decision here which each team needs to make for themselves. I also thing in larger teams it’s important to have separation of concern between those who create and those who validate.

Code in production is where money is made; broken code doesn’t make any money, it just makes people move on. Everyone is responsible for the result.

How can web developers find time for UI testing?

The answer is simple: do less. That’s right, prioritize work. Include a simple test or two in your estimation for a feature. Put another way, do more of the right things.

You may get push-back for this. Explain that you’re purposely improving your ability to turn things around faster and become more transparent about how long something really takes. Product owners and QA will get it.

Now that you have a sliver of breathing room, learn how to write a basic Selenium script over what you just created. Now you have a deliverable that can be included in CI, act as the basis for additional validation like load testing and production monitoring, and you look very good doing it.

You can do it!

Obviously, you can go to the main site, but a quick way for those with Node already installed is through WebDriver:

[full tutorial here]

For those who have never worked with Selenium before, start with this tutorial. Then go through the above.

Even if you aren’t a Node.js fan, it’s an easy to grasp the concepts. If you want to go the Java or C# route, there are plenty of tutorials on that too.

More reading: