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

Cypress has a built-in junit reporter. Add to cypress.config.js:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  reporter: 'junit',
  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-nextest has built-in JUnit support and is auto-detected by af run.

cargo install cargo-nextest

Add a CI profile with JUnit output to .config/nextest.toml in your project root:

[profile.ci]
fail-fast = false

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

Then run:

af run -- cargo nextest run --profile ci

af run automatically detects JUnit XML files under target/nextest/, so no --junit flag is needed.

cargo test (Nightly only)

On nightly Rust, cargo test has a built-in JUnit formatter. It outputs to stdout, so pipe it to a file and point af run to it:

af run --junit results.xml -- bash -c "cargo +nightly test -- -Z unstable-options --format junit > results.xml"

On stable Rust, use cargo-nextest instead (see above).


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

Install the JUnit test logger:

dotnet add package JunitXml.TestLogger

Then run with af:

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

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)

Use xcpretty to convert Xcode test output to JUnit XML:

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.