In order to scale a functional test suite, the work must be divided into parallel processes with the full stack of each isolated from the rest. At the CI server, this amounts to having a centralized Master Job that invokes parameterized Child Jobs in a fork-join pattern (using Jenkins Multijob Plugin for example) to install the application and run the tests. With each Child Job being assigned a portion of the total tests, the eventual join provides the Master Job the ability to collect the test results and coverage metrics from all jobs for centralized reporting.
Docker provides a great platform for isolating the necessary components of each Child Job. If you are already using docker images as your managed build artifacts, this process is a piece of cake. If instead your artifacts are in another form you would need to install those artifacts into an isolated db/app server pair.
Thanks to the fine contributions of folks at SeleniumHQ, the docker-selenium project provides the docker images needed to setup a selenium grid with ease. A centralized Selenium Hub container listens on a specific host port for Selenium API calls from your tests (over JSONWP). From there, the hub forwards the commands to one of several Selenium Node containers that have registered with the Hub. The Node is responsible for managing a Selenium session, browser profile, opening the browser, and any other browser interactions.
First, to create the Selenium Hub:
[root@localhost ~]# docker run -d -P --name selenium-hub selenium/hub 44274517aebdf04a6517e604275fced2b0db134375c631241da2644dcdb077b5 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 44274517aebd selenium/hub "/opt/bin/entry_point" 10 seconds ago Up 5 seconds 0.0.0.0:32770->4444/tcp selenium-hub
Next, add selenium nodes for the desired browser/version (here Firefox 32.0):
[root@localhost ~]# docker run -d -P -e FIREFOX_VERSION=32.0 --link selenium-hub:hub --name selenium-node-ff32 selenium/node-firefox cdd369b95f1a5c631241da2644dcdb077b5f04a6517e604275fced2b0db13437 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cdd369b95f1a selenium/node-firefox "/opt/bin/entry_point" 10 seconds ago Up 5 seconds selenium-node-ff32 44274517aebd selenium/hub "/opt/bin/entry_point" 1 minute ago Up 1 minute 0.0.0.0:32770->4444/tcp selenium-hub
Keep in mind that by default each selenium-node container will run only one browser session at a time. You will want to scale your number of nodes to match (or more likely, exceed) the number of parallel Child Jobs in your CI server.
Finally, point your tests to the Selenum Hub URL http://192.168.1.50:32770/wd/hub. The Hub also provides a GUI console where you can review the configuration and monitor browser use at http://192.168.1.50:32770/grid/console.
Using lightweight containers like this to divide and conquer massive functional test suites will have a profound impact on your delivery pipeline, and help reign-in the developer feedback loop. Further, with Docker's ubiquitous nature, developers often run large Selenium Grids in their local environment and farm out test groups to it before checkin.