Skip to content

[Updated] JUnit Output Requirements for Smarter Testing

Deprecation

Update September 11, 2026 We are relaxing the requireents around JUnit Output for Smarter Testing. For the best experience when it comes to dynamic test splitting and test skipping we do recommend JUnit output, it is however, not a requirement.

What’s changing

Starting September 14, 2026, CircleCI will strongly recommend that all testsuites using Smarter Testing produce valid JUnit output from their test runs. This is improves outcomes for Test Impact Analysis (TIA) and Dynamic Test Splitting.

If your testsuite does not produce valid JUnit output test selection and splitting will not have the timing and result data they need to function optimally.

Why we are communicated this change

Smarter Testing features like TIA and Dynamic Test Splitting rely on JUnit data to understand which tests ran, how long they took, and whether they passed. Without valid JUnit output, these features can’t optimally select or distribute your tests meaning you will not get the full value from Smarter Testing.

What to look for?

Thinks to watch for:

  • The outputs.junit field is not set in your testsuite’s run command
  • The JUnit XML file is missing or malformed (corrupt or empty XML)
  • The JUnit results don’t include the test atoms that were run

What you can do to optimize

  1. Ensure your testsuite’s run command uses outputs.junit

Every testsuite should declare a JUnit output path and pass it to your test runner. Here’s an example using Vitest:

name: ci tests
...
run: vitest run --reporter=junit --outputFile="<< outputs.junit >>" --bail 0 << test.atoms >>
outputs:
  junit: test-reports/junit.xml

The key parts:

outputs.junit tells CircleCI where to find your JUnit XML file

  • –outputFile=”« outputs.junit »” (or equivalent flag for your test runner) ensures the results are written to the correct location
  • –reporter=junit (or equivalent) enables JUnit output in your test runner
  1. If you use Dynamic Test Splitting, ensure JUnit results include all test atoms

When Dynamic Test Splitting is enabled, your JUnit output should reference the test atoms (files, packages, etc,. depending on your test runner) that were run. The test file paths should appear in the name, classname, or file XML attributes of your JUnit results.

name: ci tests
discover: echo "tests/index.test.ts"
run: vitest run --reporter=junit --outputFile="<< outputs.junit >>" --bail 0 << test.atoms >>
outputs:
  junit: test-reports/junit.xml  # should include test atoms in name, classname, or file XML attributes
options:
  dynamic-test-splitting: true

Adapting for your test runner

The examples above use Vitest, but the same principles apply to any test runner.

You should:

  • Enable JUnit output in your test runner (e.g., –reporter=junit for Vitest, –junitxml for pytest, –format RspecJunitFormatter for RSpec)
  • Write the output to « outputs.junit » using your runner’s output file flag Declare the output path under outputs.junit in your testsuite config

Refer to your test runner’s documentation for the specific flags to produce JUnit XML output.