I'm trying to run unit tests as part of the docker build
process, and I stumbled upon two resources:
- .NET Core Multi-Stage Dockerfile with Test and Code Coverage in Azure Pipelines
- Running .NET Core Unit Tests with Docker and Azure Pipelines (referenced by the first one).
Basically, if I understand correctly, the gist of what they suggest is to have something like this to run the tests as part of building the final docker image:
# First stage
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
LABEL test=true
# Copy files
RUN dotnet test <project-or-solution> --logger trx --results-directory /test-results
# publish the app etc.
# Second stage
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime
COPY --from=build-env ...
And then, in your pipeline (for example, Azure Pipelines), you do something like this to copy the contents of /test-results
from the first stage (and later publish the results):
id=$( docker image ls --filter=label=test=true -q | head -n1 )
docker create --name test-container $id
docker cp test-container:/test-results ./test-results
docker rm test-container
But, here's what's been happening for me: if one or more tests fail, when I create my test-container
, the directory /test-results
is not there; I think the reason is that because the tests are failing in the intermediate container responsible for running tests, the whole Docker build fails, and because of that, the changes in that intermediate container are not committed to an image, and it's only upon the success of unit tests that the /test-results
is available in the image returned by --filter=label=test=true
I've also seen another approach where a separate image with an ENTRYPOINT
is created to be able to run the tests.
What's the proper and recommended way to run C# unit tests in docker
?