Skip to content

Test Frameworks

How to connect your test framework to Automated Future.

af run works with any test framework that can produce JUnit XML output. This page shows how to configure each one.

The pattern is always the same:

af run -- <your test command with JUnit XML enabled>

af run will execute the command, find the JUnit XML file(s), and upload every test result automatically. See the CLI Reference for all options.


JavaScript / TypeScript

Jest

Install the JUnit reporter:

npm install --save-dev jest-junit

Run with af:

af run -- npx jest --reporters=jest-junit

By default jest-junit writes to ./junit.xml. To customise the output path, set the JEST_JUNIT_OUTPUT_DIR and JEST_JUNIT_OUTPUT_NAME environment variables:

JEST_JUNIT_OUTPUT_DIR=./reports af run -- npx jest --reporters=jest-junit

Or configure it in package.json:

{
  "jest-junit": {
    "outputDirectory": "./reports",
    "outputName": "junit.xml"
  }
}

Vitest

Install the JUnit reporter (included with Vitest, no extra package needed):

af run -- npx vitest run --reporter=junit --outputFile=junit.xml

Or set it in vitest.config.ts:

export default defineConfig({
  test: {
    reporters: ['junit'],
    outputFile: 'junit.xml',
  },
});

Then run:

af run -- npx vitest run

Mocha

Install the JUnit reporter:

npm install --save-dev mocha-junit-reporter

Run with af:

af run -- npx mocha --reporter mocha-junit-reporter --reporter-options mochaFile=./junit.xml

Playwright

Playwright has a built-in JUnit reporter:

af run -- npx playwright test --reporter=junit

By default this writes to stdout. To write to a file, set PLAYWRIGHT_JUNIT_OUTPUT_NAME:

PLAYWRIGHT_JUNIT_OUTPUT_NAME=results.xml af run -- npx playwright test --reporter=junit

Or configure it in playwright.config.ts:

export default defineConfig({
  reporter: [['junit', { outputFile: 'results.xml' }]],
});

Cypress

Install the JUnit reporter:

npm install --save-dev mocha-junit-reporter

Add to cypress.config.js:

module.exports = defineConfig({
  reporter: 'mocha-junit-reporter',
  reporterOptions: {
    mochaFile: 'results/junit-[hash].xml',
  },
});

Run with af:

af run -- npx cypress run

Python

pytest

af run -- pytest --junitxml=results.xml

No extra packages needed — JUnit XML output is built into pytest.

To include stdout/stderr capture in the report:

af run -- pytest --junitxml=results.xml -o junit_logging=all

unittest

Python's built-in unittest does not produce JUnit XML directly. Use unittest-xml-reporting:

pip install unittest-xml-reporting
af run -- python -m xmlrunner discover -o test-results

Java / Kotlin

JUnit 5 with Gradle

Gradle generates JUnit XML by default under build/test-results/test/. No extra configuration needed:

af run -- ./gradlew test

JUnit 5 with Maven

Maven Surefire generates JUnit XML by default under target/surefire-reports/. No extra configuration needed:

af run -- mvn test

To also include Failsafe (integration tests):

af run -- mvn verify

Go

Go's built-in test runner does not produce JUnit XML. Use go-junit-report to convert:

go install github.com/jstemmer/go-junit-report/v2@latest
af run -- bash -c "go test -v ./... 2>&1 | go-junit-report > report.xml"

If using gotestsum (recommended):

go install gotest.tools/gotestsum@latest
af run -- gotestsum --junitfile report.xml ./...

Rust

Cargo's built-in test runner supports JUnit XML output with the unstable --report-junit flag (nightly or recent stable):

af run -- cargo test -- -Z unstable-options --report-junit results.xml

Alternatively, use cargo-nextest which has built-in JUnit support:

cargo install cargo-nextest
af run -- cargo nextest run --profile ci

Add a JUnit profile to .config/nextest.toml:

[profile.ci.junit]
path = "results.xml"

Ruby

RSpec

Install the JUnit formatter:

gem install rspec_junit_formatter
af run -- bundle exec rspec --format RspecJunitFormatter --out results.xml

Or add it to .rspec:

--format RspecJunitFormatter
--out results.xml

Minitest

Install the JUnit reporter:

gem install minitest-reporters

Add to your test helper:

require 'minitest/reporters'
Minitest::Reporters.use! Minitest::Reporters::JUnitReporter.new('test-results')
af run -- bundle exec rake test

.NET

dotnet test has built-in JUnit XML support via the logger:

af run -- dotnet test --logger "junit;LogFilePath=results.xml"

If the JUnit logger is not available, install it:

dotnet add package JunitXml.TestLogger

PHP

PHPUnit

PHPUnit has built-in JUnit XML support:

af run -- ./vendor/bin/phpunit --log-junit results.xml

Or configure it in phpunit.xml:

<phpunit>
  <logging>
    <junit outputFile="results.xml"/>
  </logging>
</phpunit>

Then run:

af run -- ./vendor/bin/phpunit

Swift

XCTest (Xcode)

Xcode 16+ can produce JUnit XML via xcresulttool:

af run --junit results.xml -- bash -c "xcodebuild test -scheme MyApp -resultBundlePath TestResults.xcresult && xcresulttool format --path TestResults.xcresult --type junit > results.xml"

For earlier Xcode versions, use xcpretty:

gem install xcpretty
af run -- bash -c "xcodebuild test -scheme MyApp 2>&1 | xcpretty -r junit --output results.xml"

Elixir

Use junit_formatter:

Add to mix.exs:

{:junit_formatter, "~> 3.3", only: :test}

Add to config/test.exs:

config :junit_formatter, report_dir: "test-results"
af run -- mix test

Custom or Unsupported Frameworks

If your framework does not appear here, check whether it has a JUnit XML output option or plugin — most do. The JUnit XML format is widely supported.

If the output path is non-standard, point af run to it explicitly:

af run --junit path/to/custom-results.xml -- my-test-command

You can also upload JUnit XML to an existing test run manually:

af test-run start --label "My tests"
af junit path/to/results.xml
af test-run end

For frameworks that cannot produce JUnit XML at all, use the API to report results directly.