Docker has vastly improved the efficiency of automation and provides an ideal environment for distributed testing. Before Docker containers, spinning up and maintaining selenium grids was time-consuming and required constant maintenance as the machines had to be kept up and running at all times. The introduction of Docker containers removed the need for this maintenance. Automation has been able to scale at a much faster rate. Using Docker with EC2
instances allows us to provision the VMs, spin up the grids and tear them down all in a single automation run in less than two minutes.
We began working on UI automation about 3 years ago and one of the first tasks for the automation was to spin up a Selenium grid. Although our Selenium grid consisted of only two virtual machines, it was essential to have it up and running so our tests could run against it. We quickly realized that this would only be a temporary solution and that we would have to figure out a means to distribute our tests to increase the execution speed. As we continued growing our test base, we also increased the amount of virtual machines on the grid. At the beginning of 2017, we had about 40 Amazon EC2 instances running so that we could accommodate fast execution of the 4000 or so UI regression test cases that we have. We managed to get the full regression run to finish in under two hours, but we ran into limitations with this approach, and while it was viable,
we had to figure out a better way to tackle this problem. As the company grew, the demand for full regression runs by QA personnel increased with it, and we began running into scaling issues. Every time a QA Engineer ran a full regression it would utilize all 40 of our virtual machines, which meant that if anyone else wanted to run automation at this point, they would have to wait two hours. Spinning up additional Selenium grids was also not an ideal solution, as it would require quite a lot more resources on top of the headache of maintaining the latest Selenium binaries and drivers on each and every one.
On top of this, running so many EC2 instances at all times would become expensive very quickly. This ultimately lead to the realization that this approach is not the solution, so we began to look for a better one.
Docker is a platform that allows you to run containers within the same virtual machine. You can think of these containers as isolated virtual environments.
Without going too much into Docker, after researching it we realized that it was what we needed all along. We wanted to be able to provision a virtual machine and run Selenium Grid inside Docker containers. This will allow us to have only a single virtual machine with the same Selenium Grid that required 40 virtual machines before. Each Selenium node would now be represented by a Docker container. If we needed 20 nodes we would just run 20 Docker containers within seconds. At last, we no longer have to worry about the scalability of our Selenium grids. Each time a tester wants to run a full regression now, we will provision a new EC2 VM and spin up brand new Selenium Grids running as Docker containers. Once automation is finished with the full regression run, we will terminate the EC2 instance. This solution solved the maintenance, cost and scalability problems we were running into. Since everything is now done on demand, we no longer need the EC2 instances to be permanently up. If you need to update your Selenium Grid deployment, Docker has a simple definition file called a Dockerfile that contains all the commands the user needs to assemble the image.
The Selenium community has already written everything for us so there is no need to write your own Dockerfile from scratch unless you’d like to personally customize it. This makes it super easy to spin up your own Selenium Grid using Docker within minutes. The following snippets of code are pretty much all you need to do to have your grid up and running, assuming you have already provisioned your EC2 instance and you have Docker installed on it.
The following command will run the Selenium hub:
docker run -d -p 4444:4444 -v /dev/shm:/dev/shm -e GRID_TIMEOUT=30000 -e GRID_MAX_SESSION=5 --name selenium-hub selenium/hub:3.4.0-dysprosium
The following command will run the Selenium node:
docker run -d -e NODE_MAX_INSTANCES=5 -e NODE_MAX_SESSION=5 -v /dev/shm:/dev/shm --link selenium-hub:hub selenium/node-chrome:3.4.0- dysprosium
If you want to run 20 nodes then you will have to repeat the command above to connect more nodes to the hub. This can become a bit tedious, so instead, you will want to write your own Docker compose file. Once you have a Docker compose file, you will run something like the following command to scale up:
docker-compose scale chrome=15 firefox=15 docker-compose.yml hub: image:selenium/hub ports: -”4444:4444”firefox: image:selenium/node-firefox links: -hub chrome: image:selenium/node-chrome links: -hub
This command will spin up 15 instances of Chrome and 15 instances of Firefox. As you can see, within a few commands and a little bit of knowledge of Docker, you can completely transition to Docker and save yourself from the problems we ran across. Now, our testers can run almost a limitless number of regressions and will not have to worry about whether or not our one and only grid is available to use. With Docker in place, we can now begin working on new improvements, such as reducing our full regression time from two hours to possibly 30 minutes or less!
With Docker, scaling has become a non-issue, which has opened many other opportunities for improvement that may not have been possible before.
Currently, our process is very simple and straightforward. Running automation is just a click of a button and testers don’t have to worry about anything but the results at the end.
Our custom automation control board allows our testers to specify the branch, test group, and TestRail information. We use TestRail for test case management and we automatically update their test runs when the automation is finished.
When you trigger the run, we will provision a brand new EC2 instance and spin up the Selenium Grid with N number of nodes depending on the size of the test group you are running. As you can see, using Docker along with Selenium gives us full control on how we want to set up our grid at run time.