The modern cloud infrastructure, continuous integration & deployment processes etc have completely changed the way how applications are deployed in production nowadays. In order to release new features faster in Production, you need to reduce time we take in the each phase of the SDLC. As an automation lead/architect, It could be your responsibility to have a proper infrastructure to speed up the automated test execution! When it comes to infrastructure automation, Docker plays a major role there!
Testautomationguru already has few docker and selenium related articles which talks about setting up the dockerized selenium grid & running a docker container with a test.
Before continuing this article, I would request you to read the above 2 first! I am explaining few things here assuming that you have already read them.
This article is going to explain how to combine above 2 articles – ie running all regression testcases with multiple test suites & selenium grid with a single docker-compose file.
We have thousands of automated tests for my application. I categorize / group them, based on the application business functionality / module and create multiple test suites. So that any change in specific module can trigger corresponding test suites.
Lets assume – in our sample application for this article, we have 3 modules.
Lets also assume that, each module has hundreds of automated test cases already. In order to get my automated results as early as possible, We need to have multiple hosts + Selenium Grid set up as shown here to run the entire regression test suites!!
Setting up all the above machines with all the dependencies is a nightmare!
Lets see how we could set up the above entire infrastructure in a single compose file and execute the tests!!
For the demo, I have created a simple project as shown here. This sample project is available in Github.
In real life, we will have multiple tests for a single module. In our sample project, we have only one test. We collect all the tests for a module and create a test suite file as shown here.
<suite name="order-module" parallel="none" allow-return-values="true" > <test name="order-test"> <classes> <class name="com.testautomationguru.container.test.OrderTest"/> </classes> </test> </suite>
<suite name="search-module" parallel="none" allow-return-values="true" > <test name="search-test"> <classes> <class name="com.testautomationguru.container.test.SearchTest"/> </classes> </test> </suite>
In order to do the complete regression testing for the application, Lets assume that we need to invoke the tests for both modules as given below.
I create the below Dockerfile which creates an image which contains all the dependencies to the run the test including the testNG suite files. [I have already explained this here – Please read the article if you have not already]
FROM openjdk:8-jre-slim # Add the jar with all the dependencies ADD target/container-test.jar /usr/share/tag/container-test.jar # Add the suite xmls ADD order-module.xml /usr/share/tag/order-module.xml ADD search-module.xml /usr/share/tag/search-module.xml # Command line to execute the test # Expects below ennvironment variables # BROWSER = chrome / firefox # MODULE = order-module / search-module # SELENIUM_HUB = selenium hub hostname / ipaddress ENTRYPOINT /usr/bin/java -cp /usr/share/tag/container-test.jar -DseleniumHubHost=$SELENIUM_HUB -Dbrowser=$BROWSER org.testng.TestNG /usr/share/tag/$MODULE
So basically idea here is to create a single image which accepts browser, module as parameters – then create a container which tests specific module.
Executing below command compiles, packages the jar with all the dependencies and builds the docker image based on the above Dockerfile.
mvn clean package
Testautomationguru has already explained setting up the whole selenium grid infrastructure using docker-compose in this article – Setting up Dockerized Selenium grid.
version: "3" services: selenium-hub: image: selenium/hub container_name: selenium-hub ports: - "4444:4444" chrome: image: selenium/node-chrome depends_on: - selenium-hub environment: - HUB_PORT_4444_TCP_ADDR=selenium-hub - HUB_PORT_4444_TCP_PORT=4444 firefox: image: selenium/node-firefox depends_on: - selenium-hub environment: - HUB_PORT_4444_TCP_ADDR=selenium-hub - HUB_PORT_4444_TCP_PORT=4444
We were able to successfully create a Selenium Grid using above docker compose file. Now we are going to add the image we created to create containers to test specific module.
search-module: image: vinsdocker/containertest:demo container_name: search-module depends_on: - chrome - firefox environment: - MODULE=search-module.xml - BROWSER=firefox - SELENIUM_HUB=selenium-hub order-module: image: vinsdocker/containertest:demo container_name: order-module depends_on: - chrome - firefox environment: - MODULE=order-module.xml - BROWSER=chrome - SELENIUM_HUB=selenium-hub
Once the docker compose file is ready, the rest is very simple!!
sudo docker-compose up -d Creating selenium-hub Creating sel_firefox_1 Creating sel_chrome_1 Creating order-module Creating search-module
sudo docker-compose ps Name Command State Ports ------------------------------------------------------------------------------- order-module /bin/sh -c /usr/bin/java - ... Up search-module /bin/sh -c /usr/bin/java - ... Up sel_chrome_1 /opt/bin/entry_point.sh Up sel_firefox_1 /opt/bin/entry_point.sh Up selenium-hub /opt/bin/entry_point.sh Up 0.0.0.0:4444->4444/tcp
sudo docker-compose ps Name Command State Ports ------------------------------------------------------------------------------- order-module /bin/sh -c /usr/bin/java - ... Exit 0 search-module /bin/sh -c /usr/bin/java - ... Exit 0 sel_chrome_1 /opt/bin/entry_point.sh Up sel_firefox_1 /opt/bin/entry_point.sh Up selenium-hub /opt/bin/entry_point.sh Up 0.0.0.0:4444->4444/tcp
sudo docker-compose up | grep -e 'order-module' -e 'search-module'
sudo docker-compose down Removing search-module ... done Removing order-module ... done Removing sel_firefox_1 ... done Removing sel_chrome_1 ... done Removing selenium-hub ... done
Now the very complex selenium grid + hosts to run the java tests became very simple which you could define it in a text file. A single command creates the infrastructure in a second on a single host (you can also do that in multiple hosts) and disposes once everything is complete!
This sample project is available here.
Docker compose made our life very easier! With a single command, we create Virtual Machines (containers are light weight VMs) with required browsers, tests and executes the test. Again with another command, we bring the entire infrastructure down!!
No more environment specific issues like ‘the test is not working in the machine’ 🙂
By implementing docker in your project, you become 100% awesome as Barney!!
Happy Testing & Subscribe 🙂