Continuous integration
Snapshot tests run in CI like any other test: dotnet test fails when a snapshot differs. Three things make a failed
run easy to act on: keep what the run received, publish the HTML reports, and summarize the run on the job page.
The examples run pdiffy as a local tool, pinned in the repository's tool manifest to the same version as the PDiffy
package (see Command line), so the summary reads documents as the tests did.
What PDiffy does on a build server
- Accept mode is ignored. When
CI,TF_BUILD,JENKINS_URLorTEAMCITY_VERSIONis set, as GitHub Actions, GitLab, Bitbucket, Azure DevOps, Jenkins and TeamCity do,PDIFFY_ACCEPT=1has no effect, so a pipeline can never approve its own snapshots. - One snapshot for every OS. A snapshot is the same text on Windows and Linux, so one verified file serves a matrix build.
- Deterministic builds. If your build maps source paths (
ContinuousIntegrationBuild, common on CI), the test file's path doesn't exist on disk. PDiffy finds the test file's folder in the test project instead, using the project folder PDiffy's build file recorded. To keep snapshots in one folder, useSnapshot.ProjectFolder(see Getting started). - New snapshots. A new snapshot on a build server usually means the verified file wasn't committed, or the snapshot folder doesn't point into the checkout, and the failure says so.
GitHub Actions
This workflow runs the tests, and when they fail, adds a table of every changed snapshot to the job summary and keeps the received files and reports as an artifact:
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- run: dotnet test
# Only after a failure: summarize the changed snapshots and keep them.
- name: Summarize snapshot changes
if: failure()
run: |
dotnet tool restore
dotnet pdiffy report --all --markdown "$GITHUB_STEP_SUMMARY" --html snapshot-summary.html
- name: Keep received snapshots and reports
if: failure()
uses: actions/upload-artifact@v4
with:
name: snapshots
path: |
**/*.received.*
snapshot-summary.html
The job summary then shows a table like this:
| Snapshot | Status | Changes | By section | Can affect accessibility |
|---|---|---|---|---|
tests/Snapshots/TrailMap.received.pdfua.txt |
changed | 3: 1 moved, 1 attribute, 1 text | structure 3 | 2 |
tests/Snapshots/Guide.received.docx.txt |
new |
Download the artifact to open each report, or snapshot-summary.html, which links them all. Each report looks like
the sample report.
Note
pdiffy report exits with 1 when it finds received snapshots. After if: failure() that doesn't matter, since the
job has already failed.
Azure DevOps
steps:
- task: UseDotNet@2
inputs:
version: 10.0.x
- script: dotnet test
displayName: Test
- script: |
dotnet tool restore
dotnet pdiffy report --all --markdown $(Agent.TempDirectory)/snapshots.md --html snapshot-summary.html
echo "##vso[task.uploadsummary]$(Agent.TempDirectory)/snapshots.md"
displayName: Summarize snapshot changes
condition: failed()
- publish: $(System.DefaultWorkingDirectory)
artifact: snapshots
condition: failed()
Narrow the published folder to your snapshots folder to keep the artifact small.
GitLab CI
test:
image: mcr.microsoft.com/dotnet/sdk:10.0
script:
- dotnet test
after_script:
- dotnet tool restore
- dotnet pdiffy report --all --html snapshot-summary.html || true
artifacts:
when: on_failure
paths:
- "**/*.received.*"
- snapshot-summary.html
Bitbucket Pipelines
The after-script runs whether the tests passed or not, so it checks BITBUCKET_EXIT_CODE and only writes the summary
page after a failure. capture-on: failed keeps the received files and reports only when the step fails:
image: mcr.microsoft.com/dotnet/sdk:10.0
pipelines:
default:
- step:
name: Test
script:
- dotnet test
after-script:
- |
if [ "$BITBUCKET_EXIT_CODE" -ne 0 ]; then
dotnet tool restore
dotnet pdiffy report --all --html snapshot-summary.html || true
fi
artifacts:
- name: Snapshots
paths:
- "**/*.received.*"
- snapshot-summary.html
capture-on: failed
Bitbucket has no job summary page, so open snapshot-summary.html from the step's Artifacts tab to reach each report.
For the same reason, pdiffy findings can't write to a job summary here. When snapshots record checks, write the
findings to a file and keep it with the reports: add dotnet pdiffy findings --all --markdown snapshot-findings.md || true to the after-script, after the pdiffy report line, and snapshot-findings.md to the artifact's paths.
Review and accept locally
CI shows what changed; accepting is done on a developer machine, so the change goes through code review:
- Run the failing tests locally, or download the artifact into the same folders.
- Review the reports, or run
pdiffy report --allfor a summary. - Run
pdiffy accept --alland commit the updated.verified.*files.
Now and then, run pdiffy coverage --all to see how many snapshots still compare each section, in case tests have
drifted into ignoring the same thing everywhere, and pdiffy unused to find the
snapshots of renamed or deleted tests. When snapshots record checks,
pdiffy findings --all --markdown "$GITHUB_STEP_SUMMARY" puts a count of their problems, by rule, on the job page. In a
pull request, --since origin/main adds how many problems the pull request fixed and introduced.
See also
- Command line:
reportandacceptin full