To run dotnet test
in GitLab and have it connect to and use containerized services like databases, caches, or in this case Selenium Hub, you can use the following pattern:
- Rely on GitLab CI’s built-in
docker:dind
(“docker in docker”) service to run docker commands as job scripts. - Install
docker-compose
manually (if you know of a way to somehow use an image instead for this, let me know!) - Run
docker-compose
using a test-specificdocker-compose.yml
. - Run
dotnet test
usingdocker run [...] mcr.microsoft.com/dotnet/sdk:5.0 dotnet test [...]
.
Example xUnit Test Class
This is using xUnit, pulling the Selenium Hub URL from appsettings.json
, and grabbing the title of google.com
.
SomeBrowserTests.cs
Example appsettings.json
This is the appsettings.json
that GitLab CI will use. For local development it’s possible to use a separate appsettings.json
pointed to localhost
, since a local docker-compose
setup for development would expose the necessary ports on localhost
. However, GitLab CI creates a new container for each job script, so anything running there will have to connect from the a test container to the Selenium Hub container using the container name that docker provides via it’s magic DNS stuff. (this took me a long time to figure out, and adding a job script of docker network ls
helped.)
appsettings.CI.json
Example docker-compose.yml
Nothing fancy here (this is close to what the Selenium docs show), other than to note what network name (bridged by default) is used (some-tests
) because it will be used later when running dotnet test
.
docker-compose.some-tests.yml
Example .gitlab-ci.yml
Here’s where the rubber meets the road.
- Alpine now allows
apk add docker-compose
(so there’s no need to mess with python/pip installation ofdocker-compose
🙌). - After
docker-compose
is installed, start the Selenium Hub. - Then run the dotnet tests:
- Notice it runs the
dotnet/sdk
image in the samesome-tests
network (so that it can connect tohttp://some-selenium-hub:4444/wd/hub
) - Notice it sets the
ASPNETCORE_ENVIRONMENT=CI
(so that the test will read from theappsettings.CI.json
configuration) - Notice it mounts
-v $PWD:/app
so that the output from--logger "junit"
will be readable by the GitLab CI task runner to capture test results. This requires theJUnitTestLogger
nuget package to be installed in the test project(s). - Notice it calls
docker-compose down
, and I’m not entirely sure that’s necessary – I just like to be a good citizen.
- Notice it runs the
.gitlab-ci.yml