Skip to main content

Prepare Test Output

Actions Insights reads test result files in their native format. Your test runner must write compatible output files before the Actions Insights step runs.

Supported Formats

FormatTypical extensionsTest runners
TRX.trx.NET (dotnet test), Visual Studio
JUnit XML.xmlJava (Maven, Gradle), Python (pytest), JavaScript, Flutter (tojunit)
NUnit XML.xmlNUnit (.NET)
xUnit XML.xmlxUnit (.NET)

The action auto-detects the format from file content. Use the test-results input to specify which files to parse.

.NET (TRX)

- name: Run tests
run: dotnet test --logger "trx;LogFileName=results.trx"

- uses: mzbrau/actions-insights@v1
with:
test-results: '**/*.trx'

Java (JUnit)

- name: Run tests
run: mvn test

- uses: mzbrau/actions-insights@v1
with:
test-results: '**/TEST-*.xml'

See the Java example workflow.

Python (JUnit via pytest)

- name: Run tests
run: pytest --junitxml=test-results.xml

- uses: mzbrau/actions-insights@v1
with:
test-results: 'test-results.xml'

See the Python example workflow.

JavaScript / TypeScript (JUnit)

Jest

- name: Run tests
run: npx jest --ci --reporters=default --reporters=jest-junit

- uses: mzbrau/actions-insights@v1
with:
test-results: 'junit.xml'

Install jest-junit and configure it in jest.config.js to write junit.xml.

Vitest

- name: Run tests
run: npx vitest run --reporter=junit --outputFile=test-results.xml

- uses: mzbrau/actions-insights@v1
with:
test-results: 'test-results.xml'

See the JavaScript example workflow.

Flutter / Dart (JUnit via tojunit)

Flutter's test runner does not write JUnit XML directly. Pipe machine-readable output through the junitreport package (tojunit):

- uses: subosito/flutter-action@v2
with:
channel: stable

- name: Install tojunit
run: dart pub global activate junitreport

- name: Add pub cache bin to PATH
run: echo "$HOME/.pub-cache/bin" >> $GITHUB_PATH

- name: Run tests
run: flutter test --coverage --machine | tojunit > test-results.xml

- uses: mzbrau/actions-insights@v1
with:
test-results: 'test-results.xml'

For plain Dart projects (without Flutter), use dart test --reporter json | tojunit instead of flutter test --machine.

The tojunit converter writes test failures as <error> elements and skipped tests as <skipped/>. Actions Insights maps both to the correct pass/fail/skip counts in PR comments and reports.

See the Flutter example workflow.

Go (JUnit via gotestsum)

- name: Run tests
run: gotestsum --junitfile test-results.xml -- ./...

- uses: mzbrau/actions-insights@v1
with:
test-results: 'test-results.xml'

Install gotestsum before running tests (e.g. go install gotest.tools/gotestsum@latest).

Ruby (JUnit via rspec_junit_formatter)

- name: Run tests
run: bundle exec rspec --format RspecJunitFormatter --out test-results.xml

- uses: mzbrau/actions-insights@v1
with:
test-results: 'test-results.xml'

Add the rspec_junit_formatter gem to your project.

Multiple Result Files

Use a glob pattern to match multiple files:

with:
test-results: '**/*.{trx,xml}'

Troubleshooting

  • No results found — verify the glob matches your output path and that tests ran before the Actions Insights step
  • Wrong format detected — ensure XML files use a supported schema; place specific parsers before generic ones
  • Empty report — check that test files are not in .gitignore paths excluded from the workspace

Code Coverage

When coverage-enabled: true, Actions Insights parses coverage files alongside test results. Supported formats: Cobertura (including Coverlet output), OpenCover, LCOV, and JaCoCo. Coverage appears in PR comments, job summaries, HTML artifacts, and the history dashboard.

FormatTypical outputDefault glob
Cobertura XMLcoverage.cobertura.xml**/coverage.cobertura.xml
OpenCover XML*.opencover.xml**/coverage.opencover.xml
JaCoCo XMLjacoco.xml**/jacoco*.xml
LCOVlcov.info**/lcov.info

Set coverage-files to a glob matching your test runner's output. Use comma-separated patterns for multiple globs.

.NET (Cobertura via Coverlet)

- name: Run tests
run: dotnet test --collect:"XPlat Code Coverage" --results-directory ./coverage --logger "trx;LogFileName=results.trx"

- uses: mzbrau/actions-insights@v1
with:
test-results: '**/*.trx'
coverage-enabled: true
coverage-files: '**/coverage.cobertura.xml'

See the .NET example workflow with coverage.

Java (JaCoCo)

- name: Run tests
run: mvn test jacoco:report

- uses: mzbrau/actions-insights@v1
with:
test-results: '**/TEST-*.xml'
coverage-enabled: true
coverage-files: '**/jacoco*.xml'

Configure the JaCoCo Maven plugin to write XML reports. Gradle projects typically use the JaCoCo plugin with reports { xml.required = true }.

Python (LCOV via pytest-cov)

- name: Run tests
run: pytest --junitxml=test-results.xml --cov --cov-report=lcov:coverage/lcov.info

- uses: mzbrau/actions-insights@v1
with:
test-results: 'test-results.xml'
coverage-enabled: true
coverage-files: 'coverage/lcov.info'

For Cobertura XML output instead, use --cov-report=xml:coverage/coverage.xml and set coverage-files: 'coverage/coverage.xml'.

JavaScript / TypeScript (LCOV via Vitest)

- name: Run tests
run: npx vitest run --reporter=junit --outputFile=test-results.xml --coverage

- uses: mzbrau/actions-insights@v1
with:
test-results: 'test-results.xml'
coverage-enabled: true
coverage-files: '**/lcov.info'

Jest (LCOV via nyc or built-in coverage)

- name: Run tests
run: npx jest --ci --coverage --coverageReporters=lcov

- uses: mzbrau/actions-insights@v1
with:
test-results: 'junit.xml'
coverage-enabled: true
coverage-files: 'coverage/lcov.info'

Optional: fail when coverage is missing

with:
coverage-enabled: true
coverage-files: '**/coverage.cobertura.xml'
coverage-fail-if-missing: true

See Configuration Reference — Code coverage for all coverage inputs.

Next Step

Add the action to your workflow.