Repository navigation
Runner Coverage 2026 10 26
A coverage review (2026-10-26) estimated that Testosterone supported about 23% of test framework usage natively (pytest, Behave/BehaveX, Playwright) and could record about 94% through JUnit XML. A third of that 94% needed an extra reporter package first (jest-junit, a .NET JUnit logger, gotestsum, ...), and JUnit drops what the runner knew: describe blocks, retries, files that failed before any test ran, tags. The aim is for Testosterone to be the default results history for any test tool, so the common runners should work with the output they already write, with no extra install.
testo_core/reporting/junit_import.py stays the one entry for every result file (stage junit_xml globs, testo ingest, POST /api/v1/ingest). It now recognises a file by its content, not its name, and hands it to that runner's importer. Each importer writes the same Allure result dicts, so nothing after the import changes.
| File | Written by | Importer |
|---|---|---|
JUnit XML (<testsuite> / <testsuites>, and any other XML) |
most runners | junit_import.py |
Playwright JSON (suites list) |
--reporter=json |
playwright_import.py |
Jest / Vitest JSON (testResults list) |
jest --json, vitest --reporter=json
|
jest_import.py |
TRX (<TestRun>) |
dotnet test --logger trx (xUnit, NUnit, MSTest) |
trx_import.py |
go test -json lines (Action / Package events) |
go test -json |
gotest_import.py |
Robot Framework output.xml (<robot>) |
robot |
robot_import.py |
Allure *-result.json
|
any Allure adapter | allure_passthrough.py |
-
Identity. Each importer builds a stable
fullName:file › describe › titlefor Jest/Vitest (paths relative to the repo, or to the report's common folder when made elsewhere),Namespace.Class.Methodfor TRX,package.Test/subtestfor Go, Robot's long name. These are also the names the runners' own "run only this test" options take, which later rerun commands rely on. -
What JUnit lost. A Jest test that passed on retry is flaky; a test file that failed to load is one
brokenresult; TRX data rows are one result each; a failed Go package with no failing test (build error) is onebrokenresult; a Go parent test counts only when it failed on its own, so a failing subtest is not counted twice; Robot tags become Allure tags. -
Allure folders.
testo ingest allure-results/(a folder argument stands for its files) copies each result with the attachments it names, from the same folder only. Containers and the folder's settings files are skipped without a warning. -
Server uploads.
POST /api/v1/ingestkeeps a file's safe name and suffix (an Allure result names its attachments by file name) and reads every stored file by content. -
Native JavaScript stages. New equipment
jest,vitest(frameworks/jest_adapter.py) andcypress(frameworks/cypress_adapter.py) run the runner throughnpxand add the report Testosterone reads, likeplaywrightdoes: Jest's--json --outputFile, Vitest'sjsonreporter (andvitest run, never watch mode), Cypress's built-injunitreporter. Jest and Vitest take--maxWorkersfromworkers; Cypress can't parallelise without its cloud, soworkerswarns there. A stage that sets its own reporter keeps it. -
Rerun commands for more runners.
services/rerun_commands.py(the run page's "Rerun these tests") also uses theframeworklabel each imported result carries, so an ingested file gets its own runner's command: Jest/Vitest (test files plus-t '^(describe path title|...)$'),go test -run '^(TestA|TestB)$' <packages>(top-level tests, which rerun their subtests),dotnet test --filter FullyQualifiedName=...(data rows rerun their method),robot --test <name> <root suite folder>, and for JUnit XML from a JVM buildmvn test -Dtest=Class#m1+m2orgradle test --tests Class.methodwhen the run's target repo has apom.xmlor a Gradle build. The pytest guess for dotted JUnit names now needs atest_*.py/*_test.pyfile, the files pytest collects, so a Java class is no longer offered as a pytest module. Cypress gets none: its JUnit file does not name the spec file. - Unknown files are skipped with a note in the stage log, as malformed JUnit always was. They never fail the stage on their own.
- Jest, Vitest, .NET, Go and Robot suites can be recorded with the output their runner writes by default. JUnit XML keeps working for everything else.
- Detection reads each file once more than before (a sniff, then the parse). Result files are small next to the test run.
-
historyIdstill hashes the stage's tool withfullName, so moving a suite from JUnit XML to its runner's own format starts a new history for its tests (different names). - Allure containers (fixtures) are not shown; Testosterone has no place for them.
A comparison with Qualflare (a hosted test-results service that lists XCTest, RSpec, k6 and Espresso among its 23+ frameworks) found these four still needed a JUnit reporter or weren't covered. Same pattern, same entry point:
| File | Written by | Importer |
|---|---|---|
RSpec JSON (examples list + summary) |
rspec --format json |
rspec_import.py |
k6 summary (metrics + root_group) |
k6 run --summary-export=..., or handleSummary writing JSON.stringify(data)
|
k6_import.py |
xcresulttool JSON (testNodes tree) |
xcrun xcresulttool get test-results tests --path X.xcresult (Xcode 16+) |
xcresult_import.py |
Android instrumentation JUnit (suite device property) |
connectedAndroidTest (Espresso, UI Automator, Compose) |
junit_import.py |
-
RSpec.
full_nameisspec file › full description. Pending examples are skipped; errors outside examples (a spec file that failed to load) become onebrokenresult. Rerun:rspec <files> -e <description>, withbundle execwhen the target repo has aGemfile. -
k6. A load test has no test cases, so each check and each threshold becomes one result (
checks › group › name,thresholds › metric › expression). A check with any failed iteration isfailed("3 of 120 failed"); a crossed threshold isfailedwith the metric's values. Both the--summary-exportshape (keyed by name, thresholdtrue= failed) and thehandleSummaryshape (lists,{"ok": false}) are read. Results have no duration (each would span the whole run). No rerun command: only the whole script reruns. -
XCTest. The
.xcresultbundle is a database only Apple's tool reads, so the input is the JSONxcresulttoolexports; reading the bundle directly would need macOS.full_nameisBundle/Suite/test(), the-only-testing:form. A test that passed on a repetition after failing is flaky. No rerun command:xcodebuildalso needs a scheme and destination the results don't record. -
Android. The Android Gradle plugin's JUnit XML already worked; suites that name a
deviceare now labelledandroid(and the device ashost), so the run page offers./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=Class#method. In a project with several modules that have instrumentation tests, run it on the module's own task.
Builds on Command Adapter and JUnit Import, Playwright JSON Import and Ingest and Team Server.
Generated from docs/Specs & ADRs/Runner Coverage - 2026-10-26.md. Edit it there; changes made in the wiki are overwritten.
Architecture
CLI Commands
Processes & Guides
- CI-CD Pipeline Setup
- E2E Harness Operations Guide
- GitLab Pages Demo
- Publishing Docker Images
- Publishing to Artifactory
- Publishing to PyPI
- Shared Resource Pools
- Team Server
Prompts & Snippets
Roadmap & Strategy
Specs & ADRs
- Alerts Where Developers Look - 2026-10-22
- Architecture Consolidation - 2026-10-06
- BehaveX Reports - 2026-10-21
- Command Adapter and JUnit Import - 2026-09-25
- Config JSON Schema - 2026-10-22
- Delta Comparison Policy
- Docs Site - 2026-10-19
- Docs Vault and Wiki Sync - 2026-10-07
- Flaky Test Quarantine - 2026-10-22
- GitHub Action PR Comment - 2026-10-19
- Ingest and Team Server - 2026-10-22
- Interview Readiness Fixes - 2026-10-07
- Library Packaging
- Open Source Features - 2026-10-19
- Phase 3 Delta Comparison Engine Plan
- Phase 3 Unified Dashboard Plan
- Phase 4 BYOK and Failure Analysis
- Phase 5 UI Redesign - Cycles-First Navigation
- Playwright Adapter - 2026-10-19
- Playwright JSON Import - 2026-10-22
- Plugin API - 2026-10-19
- Product Roadmap Work - 2026-10-25
- Product to Ten - 2026-10-25
- Project Health - 2026-10-26
- Qualflare Follow-ups - 2026-10-26
- Specs & ADRs
- Repository Pattern - Database-Agnostic Refactor
- Resource Lifecycle Hooks - 2026-10-26
- Resource Pools and Leases - 2026-10-26
- Runner Coverage - 2026-10-26
- Scale Runs and Stages - 2026-10-24
- Switchable Team Features - 2026-10-24
- Throwaway Stage Containers - 2026-10-24
- UI Restyle - 2026-10-19
Testing Workflows
Vault