Failing Azure DevOps Pipeline builds if unit tests fail
12 Mar 2023
- We’ve built the world’s tiniest webserver.
- We’ve added unit tests that can help us predict whether it would run “correctly.”
- We’ve told Azure DevOps (“ADO”) Pipelines to auto-build a runnable web server for us each time we update Git-tracked source code.
- How about having Azure DevOps fail the auto-build if our unit tests fail?
Let’s do it!
See the sample codebase on GitHub.
Prerequisites
- Please work your way through all 3 of the exercises mentioned at the top of this article so that you’re familiar with “building” and “running” a webserver from source code, “unit testing” it, and “making a CI/CD build pipeline in Azure DevOps.” (Although in this case, we still won’t be “running” the server, per se.)
- Have an account in Azure DevOps. You can get one:
- From Microsoft for free but with a credit card on file.
- From Microsoft for free without a credit card as a student.
- From Microsoft without a credit card through a Visual Studio subscription if you have one at work.
- For 4 hours at a time through an A Cloud Guru subscription (personally, I’d rather get 1 yearly charge from ACG than give Microsoft my credit card and expose myself to getting hacked and running up an “infinity” bill).
No need to install anything onto your computer – we’ll do everything in this article through a web browser.
How the pipeline will behave
The YAML-formatted file “/cicd/my-azure-build-pipeline.yml
” (from the sample codebase you just copied) forces any ADO Pipeline running it to walk through all of the same sequential steps as mentioned in the previous article, plus a few additional ones:
- (Execute only on edits to “
main
” branch, same as before.) - (Borrow a computer from Microsoft, same as before.)
- (Install Node.js and NPM, same as before.)
- (Install specific Node modules, same as before.)
- New: Run unit tests. It does this by executing a “
npm run test
” command on the agent’s operating system. - New: Publish results of unit test execution to the ADO project’s “Test Plans” -> “Runs” dashboard.
- Conditional only if tests PASS:
- (Build
/dist/
, same as before.) - (Copy
/dist/
to an “artifact staging directory,” same as before.) - (Copy the “artifact staging directory” contents to a longer-lived “Artifact” named “
MyBuiltWebsite
,” same as before.)
- (Build
Again, after these steps finish executing, it’s safe for Azure DevOps to let the agent (the Linux computer we borrowed from Microsoft) self-destruct.
Running a successful build
Follow these steps from the previous article, with a few changes:
- “Importing my sample codebase into ADO Repos, but…”
- Only instead of importing a copy of
...03-ado-build.git
… - Import a copy of:
https://github.com/kkgthb/web-site-nodejs-04-ado-tests.git
- Only instead of importing a copy of
- “Telling Azure Pipelines to build when code changes” -> “Forcing ADO to use our YAML pipeline code.”
- “Running the pipeline by editing code.”
- Please only edit
README.md
for now.
- Please only edit
- “Validating the pipeline ran correctly.”
- If you look at the job logs, you’ll see that there were more steps involved to execute the pipeline.
- Logs from the pipeline step that runs unit tests will have output that looks somewhat like this “passing test” output from earlier on your own computer.
- In the job summary’s 4th column, under “Tests and coverage,” there should also be a clickable link that says “100% passed.” If you click it, you’ll see a green donut chart showing that 2 of 2 tests passed.
Also follow these steps:
- In the left-hand navigation of Azure DevOps, click on “Test Plans.”
- Beneath that, click “Runs.”
(Note: this particular pages’s dedicated URL will be something like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_testManagement/runs
.) - Under “Recent test runs” to the right, you should see a test in “completed” state.
- Double-click it to see a lovely dashboard with green donut and bar charts indicating that 2 of 2 tests passed.
- Click the “Test results tab to see each of the 2 tests listed separately (they’re also double-clickable, though in this case there’s not really anything in there that adds useful detail).
Running a failed build
Repeat the steps from the previous article’s “Running the pipeline by editing code” section.
Only instead of editing a README.md
file…
Edit the contents of line 12 of the file at /src/__tests__/my-first-test.js
and replace the word “World” with the word “Goodbye” so that instead of looking for "Hello World!"
your test is looking for "Hello Goodbye!"
.
Then repeat the steps from the previous article’s “Validating the pipeline ran correctly” section.
Only this time:
- Under “Related,” the summary will say “0 published” and it won’t be hyperlinked.
- This is good – we wanted to fail the build if our unit tests failed! Who wants to risk building bad code and leaving it lying it around where it might accidentally get deployed into production? Not me.
- Logs from the pipeline step that runs unit tests will have output that looks somewhat like this “failing test” output from earlier on your own computer.
- In the job summary’s 4th column, under “Tests and coverage,” there should also be a clickable link that says “0% passed.” If you click it, you’ll see a red donut chart showing that 0 tests passed and 2 failed.
Also follow these steps:
- In the left-hand navigation of Azure DevOps, click on “Test Plans.”
- Beneath that, click “Runs.”
(Note: this particular pages’s dedicated URL will be something like
https://dev.azure.com/YOUR-ADO-ORG-NAME/YOUR-ADO-PROJECT-NAME/_testManagement/runs
.) - Under “Recent test runs” to the right, you should see a test in “completed” state.
- Double-click it to see a lovely dashboard with red donut and bar charts indicating that 2 of 2 tests failed.
- Click the “Test results tab to see each of the 2 tests listed separately (they’re also double-clickable, though in this case there’s not really anything in there that adds useful detail).
Extra credit – test-driven development
Repeat the steps from the previous article’s “Running the pipeline by editing code” section.
Only instead of editing a README.md
file…
Edit the contents of line 6 of the file at /src/web/server.js
and replace the word “World” with the word “Goodbye” to match the unit test you updated earlier.
Then repeat the steps from the previous article’s “Validating the pipeline ran correctly” section. Once the pipeline finishesrunning, congratulate yourself that once again, your source code successfully builds into a webserver runtime “artifact” and that all your ADO Test Runs result dashboards are colored green.
Credits
- Rupesh Tiwari’s “Publishing Test Results Using JEST in Angular” for teaching me how to reformat JEST output into JUnit format, one of the formats that ADO’s
PublishTestResults
command can read.
Posts in this series
- Part 1 - Source code that builds locally into a Node.js Hello World webapp
- Part 2 - Locally unit-testing source code for a Node.js Hello World webapp
- Part 3 - Protecting Git branches in Azure DevOps repositories
- Part 4 - Making Azure DevOps Pipelines build a Hello World webapp from Git-tracked source code changes
- Part 5 - This Article
- Part 6 - Logging your command line into Azure
- Part 7 - Provisioning an Azure Resource Group
- Part 8 - Provisioning Azure App Services to host your Hello World webapp
- Part 9 - Provisioning Azure AD Service Principals that can deploy built webapps onto your Azure App Service resources
- Part 10 - Provisioning Azure DevOps Service Connections that let ADO Release Pipelines leverage Azure AD Service Principals for sensitive CI/CD tasks
- Part 11 - Deploying a built webapp onto Azure App Service with ADO Release Pipelines