Home Fixing Broken Unit Test Execution in Dockerfile

Fixing Broken Unit Test Execution in Dockerfile

In my demos, I frequently feature code snippets from my “Microservice Series - From Zero to Hero” series.

Everything was running like a charm during spring, but upon revisiting it in October, I stumbled upon a puzzling scenario - a broken build. Especially since nothing had changed since I ran the pipeline successfully the last time

In this post, I will explain how to fix this issue and update the pipeline accordingly.

This post is part of “Microservice Series - From Zero to Hero”.

Analysing the Problem

You can find the code of the demo on GitHub.

When I attempted to run the pipeline, I encountered an error when the pipeline was trying to retrieve the test results from the container it had created. The error message indicated that the container containing the test results could not be located.

The testcontainer was not found

The testcontainer was not found

Upon a thorough examination of the build process, it became evident that the tests were not being executed, leading to the absence of a layer within the image that should have contained the test results. To identify the root cause of this abrupt termination of the test execution, I delved into the Dockerfile. Let’s take a closer look at the relevant part of the Dockerfile:

This portion of the Dockerfile employs the BuildId build argument and uses it as the label for the test layer. This label plays a crucial role after the build process, as it’s used to identify the layer containing the test results, enabling the pipeline to extract them from the image.

Through my investigation, I discovered that the tests were only executed when the line “FROM build AS test” was present. This statement is essential to ensure that the correct image is used for running the tests.

Resolving the Issue and Re-enabling the Unit Tests

Docker provides a useful parameter called --target, which allows you to selectively execute specific portions of the Dockerfile. This parameter enables us to trigger the execution of tests using the following command:

However, it’s important to note that you can only pass one --target parameter at a time. As a result, you’ll need to execute the docker build command separately for each target in your Dockerfile, such as “tests” and “dacpac.” Additionally, it’s necessary to run a docker build command without specifying any targets to build the image as originally intended. While this may appear somewhat complex and time-consuming, Docker caches each layer. Thus, when you run docker build with the “test” target, and subsequently execute a docker build without specifying any targets, the second run will complete within seconds due to the cached layers. This approach ensures efficient building while re-enabling the execution of unit tests.

Updating the CI Pipeline with the Necessary Modification

To successfully address this issue, the final step involves updating the pipeline to incorporate the building of both the “test” and “dacpac” stages, followed by the regular Docker build process. Implement the following command within the DockerBuildAndPush.yml file:

When you execute the pipeline, you’ll observe three Docker build tasks in action, and the pipeline will complete successfully. It’s worth noting that the first build task (“Run tests”) consumed 1 minute and 12 seconds, while the second and third build tasks (“Build Database” and “Build Docker Container”) finished in just 23 seconds and 4 seconds, respectively.

The-Pipeline succeded with the three docker build tasks

The-Pipeline succeded with the three docker build tasks

This updated configuration ensures the smooth execution of your pipeline while efficiently building the necessary components.


In conclusion, we encountered a puzzling issue in our microservices project, where unit tests were no longer executing as expected.

By leveraging Docker’s --target parameter, we were able to selectively run the required stages of our Dockerfile, thereby re-enabling the execution of unit tests. These changes were seamlessly integrated into our CI pipeline, resulting in a successful build process.

You can find the code of the demo on GitHub.

This post is part of “Microservice Series - From Zero to Hero”.

This post is licensed under CC BY 4.0 by the author.

Article - Azure Arc - The Gateway to the Cloud Part 1

Article - Azure Arc - The Gateway to the Cloud Part 2 - Automated Deployments

Comments powered by Disqus.