Skip to content
BETAGuardrails are in beta. The library, the configuration format and the CLI command can still change.

Guardrails / tests

The build published its test results

tests/results-published@v1

The build left a test report that can be read, naming at least the cases the team expects, rather than reporting nothing at all.

Idtests/results-published
Versionv1
Categorytests
Default severityerror
Interpreterpython3
Timeout30 seconds
Violations tolerated0
Collectstests

Collectors

This guardrail gathers nothing itself. It depends on the collectors below, which the CLI runs once per build before any check, and reads what they found out of GUARDRAIL_FACTS. A collector that collects nothing skips this guardrail rather than failing it.

CollectorGathersInputs it is given
testsThe test results the build already wrote, read from whichever report format it left behind and normalized into one shape: the totals across every report, and the cases that failed, errored or were skipped. The passing cases are left out, because a guardrail gates on the others and Buildnote already carries every case as a test event. Nothing identifies a case across reports, so a build writing both a report per class and a merged one counts every case in both.none

The inputs above are this guardrail's own, passed straight through. Configuring one in buildnote.json changes what is collected, and two guardrails configured the same way share the one collection.

Configuration

json
{
  "guardrails": {
      "failOn": "error",
      "comment": true,
      "checks": [
          {
              "use": "tests/results-published@v1",
              "severity": "error",
              "with": {
                  "minTests": "1"
              },
              "exemptions": []
          }
      ]
  }
}

Inputs

InputDescriptionDefaultEnvironment variable
minTestsFewest cases the reports must name between them. A report naming none is a file, not a test run.1GUARDRAIL_INPUT_MINTESTS

How to fix

Write the test reports the runner already produces into the workspace before buildnote guardrails runs, and keep them there. Gradle writes JUnit XML into build/test-results/, and most runners take a flag:

bash
./gradlew test
pytest --junitxml=junit.xml
dotnet test --logger trx

The absence is the violation. A pipeline whose test step went green but left nothing behind cannot be shown to have run a single test, and a report naming no cases is that same absence in a file. Where a job genuinely has no tests, leave the guardrail off that job rather than lowering minTests to zero.

More in tests

  • tests/coverage-floor. The coverage the build measured sits at or above the line and branch floors the team sets. Both floors default to zero, so the guardrail reports the number until a team chooses one.
  • tests/no-failures. Every case the test reports name either passed or was skipped, so nothing red was carried past the gate.
  • tests/no-skipped-growth. The reports name no more skipped cases than the budget allows. The budget is a fixed number this guardrail is configured with rather than a comparison against the previous build, so it catches growth only as far as the team lowers the number when a skip comes back.

All 4 tests guardrails

Buildnote Limited
Registered in England and Wales, Reg: 16140412