Simplify running and testing your tests and maybe even get more people to run and use them.
Add a simple but easy-to-use docker-compose orchestration framework using a Selenium Standalone browser container to your browser test projects. View the tests using the included Virtual Network Computing (VNC) Server.
Use it locally to simplify using and testing your tests.
Use it in Continuous Integration/Continuous Deployment (CI/CD) to simplify workflows and keep the logic with your tests.
#docker-compose #unixshellprogramming #docker-selenium
In the continuation of this three part series, I will show you how you can add a docker-compose framework to your automated browser tests (e.g. end-to-end, acceptance) with a single command to spin it up, run it, and tear it all back down.
We'll cover and practice some docker-compose concepts and Unix shell programming.
This is Part 2 where we will continue to cover The How of adding this framework, specifically...
- The
Dockerfile
- The Don't Repeat Yourself (DRY) set of
docker-compose
files
You will want a Dockerfile
to build the Docker image for your
browser tests project. You may already have one.
For your docker-compose framework, you will want to do these two
things in your Dockerfile
...
- Use the
runtests
script that you just added as theCMD
for your image so that it has your defaults and waits on the Selenium browser to be fully up before running the tests - Use
CMD
and notENTRYPOINT
so that it is easier to override and specify a command to run to make your docker-compose framework more flexible
Here's an example of a simple Dockerfile
for a .NET/C# Selenium
browser test project....
FROM mcr.microsoft.com/dotnet/sdk:5.0
COPY . .
WORKDIR /BrowserTests
CMD ./script/runtests
I find that in life, the best principles are universal. For instance,
the principle of Don't Repeat Yourself which works so well when
telling stories also works well in maintaining docker-compose
files.
docker-compose allows you to specify multiple docker-compose
files
which can override previous configurations. This can remove duplication
and provide greater flexibility by simply adding another docker-compose
file. This also lets you make smaller, more cohesive and portable
docker-compose
files.
At the least, you will want two docker-compose
files...
- A
docker-compose.yml
file for your browser tests' default specification - A
docker-compose.selenium.yml
file for adding the Selenium Standalone browser
Start with the base docker-compose.yml
for your tests.
This should be the base or "production" version for your tests (i.e. used in CI/CD).
Here's an example docker-compose.yml
for your browser tests...
version: '3.4'
services:
browsertests:
image: "your-org/your-browser-tests:${BROWSERTESTS_TAG:-latest}"
container_name: ${BROWSERTESTS_HOSTNAME:-browsertests}
This is a pretty simple docker-compose
file that defines a
browsertests
service for your-org/your-browser-tests
image.
The :${BROWSERTESTS_TAG:-latest}
allows you to specify a tag
for your image using the BROWSERTESTS_TAG
environment variable.
If it is not specified, it uses the default value latest
. This
is useful for testing images when developing the tests.
The container_name: ${BROWSERTESTS_HOSTNAME:-browsertests}
allows
you to specify a container name and hostname for networking using
the BROWSERTESTS_HOSTNAME
environment variable. If it is not
specified, it uses the default value browsertests
. This can
be useful in CI/CD if unique running container names are needed.
I picked up this ability to use and assign default values to environment variables in docker-compose from the Docker documentation on environment variables.
However, this is a shell programming technique, yet another good reason to know some shell.
Now add the docker-compose.selenium.yml
configuration file.
Here's an example docker-compose.selenium.yml
file...
version: '3.4'
services:
browsertests:
environment:
- BROWSER=${BROWSER:-chrome}
- REMOTE=http://${SELENIUM_HOSTNAME:-seleniumbrowser}:4444/wd/hub
- REMOTE_STATUS=http://${SELENIUM_HOSTNAME:-seleniumbrowser}:4444/wd/hub/status
depends_on:
- seleniumbrowser
seleniumbrowser:
image: ${SELENIUM_IMAGE:-selenium/standalone-chrome:latest}
container_name: ${SELENIUM_HOSTNAME:-seleniumbrowser}
shm_size: 2gb
volumes:
- /dev/shm:/dev/shm
ports:
- "5900:5900"
- "7900:7900"
healthcheck:
test: ["CMD-SHELL", '/opt/bin/check-grid.sh --host 0.0.0.0 --port 4444']
interval: 15s
timeout: 30s
retries: 5
This one is not so simple, but demonstrates how docker-compose
files can be additive and override previous files. We would call
these two files in this order...
docker-compose -f docker-compose.yml -f docker-compose.selenium.yml <docker command>
This order is important because the docker-compose.selenium.yml
adds on and/or
overrides settings from your docker-compose.yml
. Files you list later on the
command line override those you listed previously.
You can learn more about multiple compose files from the Docker documentation on multiple compose files
Start with configuring the seleniumbrowser
service...
Although it's later in the .yml
file, you start with the docker-compose
service for the Selenium browser because information on its configuration
is needed for setting environment variables in the service for your tests.
This is how you will connect the Selenium browser to your browser tests.
This part below defines the seleniumbrowser
service, and...
- Lets you specify a specific selenium standalone image
(i.e. chrome, firefox, specific version, etc.) using the
SELENIUM_IMAGE
environment variable or setsselenium/standalone-chrome:latest
as the default - Lets you specify a container name which would be used
as the hostname for the Selenium browser or sets the
default
seleniumbrowser
(you will need to give this address to your browser tests service) - Sets the defaults required by Selenium for the
shm
andvolumes
(storage)
seleniumbrowser:
image: ${SELENIUM_IMAGE:-selenium/standalone-chrome:latest}
container_name: ${SELENIUM_HOSTNAME:-seleniumbrowser}
shm_size: 2gb
volumes:
- /dev/shm:/dev/shm
Next you add the VNC server port mapping to your localhost so that you can see the tests running...
ports:
- "5900:5900"
- "7900:7900"
Port
5900
is for connection with a VNC client at vnc://localhost:5900Port
7900
is for connection with the noVNC browser client at http://localhost:7900/
Now as good practice, we add a health check to our seleniumbrowser
...
healthcheck:
test: ["CMD-SHELL", '/opt/bin/check-grid.sh --host 0.0.0.0 --port 4444']
interval: 15s
timeout: 30s
retries: 5
Now add the browsertests
service configuration...
Now that you have configured the seleniumbrowser
service,
you will use some of this information to add additional
configuration to your browsertests
service and connect
the two docker-compose services.
This section adds the environment variable settings that you will want....
environment:
- BROWSER=${BROWSER:-chrome}
- REMOTE=http://${SELENIUM_HOSTNAME:-seleniumbrowser}:4444/wd/hub
- REMOTE_STATUS=http://${SELENIUM_HOSTNAME:-seleniumbrowser}:4444/wd/hub/status
This sets the REMOTE_STATUS
environment variable which is used by your
runtests
script.
You should also have an environment variable implemented in your browser tests that lets you specify the URL of the remote Selenium browser and possibly the type of browser (e.g. chrome)
This section tells docker-compose to ensure that the seleniumbrowser
service must be running whenever you run your browsertests
service...
depends_on:
- seleniumbrowser
This dependency allows you to run just the browsertests
service
but have it also start the seleniumbrowser
service. You will use
this in your dockercomposerun
helper script.
I put this
docker.compose.selenium.yml
file together over several iterations using the Selenium Docker documentation for the specific configuration values.
Test your docker-compose
files to ensure that they work and run your tests...
-
Make sure you have your browser tests image already built if you are pulling the image in your
docker-compose.yml
file -
To run your
docker-compose
framework, use the command...docker-compose -f docker-compose.yml -f docker-compose.selenium.yml run browsertests
-
Check that you can see your tests running in the VNC server
-
To tear down your
docker-compose
framework, use the command...docker-compose -f docker-compose.yml -f docker-compose.selenium.yml down
This is the end of Part 2. Continue to Part 3.