SupercovDocumentation

Documentation

Supported languages and test suites

Check supported languages, test runners, attribution levels, builds, and remote execution.

JavaScript

Supercov supports JavaScript, TypeScript, Rust, Python, and Ruby today. Start with the same test command the repository already uses; Supercov detects supported runners inside that command.

npx supercov -- npm test
npx supercov -- npx playwright test
supercov -- cargo test
uvx --from supercov-cli supercov -- pytest
supercov -- rspec

Language support

LanguageStatusStart with
JavaScriptAvailablenpx supercov -- npm test
TypeScriptAvailablenpx supercov -- npm test
RustAvailablesupercov -- cargo test
PythonAvailableuvx --from supercov-cli supercov -- pytest
RubyAvailablesupercov -- rspec
ZigComing soon
PHPComing soon
CComing soon

The npm-distributed CLI requires Node.js 22 or newer for every language.

What exact and aggregate mean

Exact attribution means Supercov knows which test, attempt, retry, and runner produced the coverage. Queries such as test, passed, and failed can use that identity.

Aggregate coverage means Supercov knows the source executed but cannot truthfully assign it to one test. Whole-run gaps and file queries still work; per-test questions are limited.

Supercov reports the level it actually observed. It does not guess.

JavaScript and TypeScript

RunnerAttribution
PlaywrightExact per test, worker, retry, outcome, action, and assertion phase
VitestExact per test, with setup execution kept separate
JestExact per test, including parameterized tests, with the user’s own configuration, setup files and reporters kept; passing expect occurrences are identified for assertion maps
node:testExact per test
AVA and MochaAggregate structural coverage
Other Node-based runnersAggregate when their processes remain visible to Supercov
Browser component runners without an adapterAggregate structural coverage

One command may launch several runners. Supercov combines their evidence into one run and preserves runner identity wherever the runner exposes it.

Builds and source formats

JavaScript and TypeScript projects may use Vite, Next, Turbopack, Webpack, esbuild, SWC, tsc, or no build step. ESM, CommonJS, JavaScript, JSX, TypeScript, and TSX are supported.

Supercov instruments an isolated copy. It does not ask you to add an import, reporter, plugin, or alternate build output.

If tests import compiled output such as dist/ or launch a script that uses it, Supercov runs the project’s build inside the isolated copy before testing. Keep using your normal test and build commands. Instrumentation does not require changing the project’s TypeScript settings.

For assertion maps, Node, Vitest, Jest and Playwright’s Node-side assertions supply supported passing-occurrence evidence. Custom assertion wrappers and browser-side checks can have additional observation limits. See Assertion evidence before interpreting a missing occurrence.

Browsers, servers, and child processes

Playwright support includes Chromium, Firefox, and WebKit, along with pages, frames, popups, workers, request contexts, WebSockets, and test-launched child processes where the runner exposes their identity.

Browsers a suite launches itself are covered too. A fixture that calls chromium.launchPersistentContext, or launch/connect and hands out its own contexts and pages in place of Playwright’s page fixture, is adopted by each test’s collector: its pages are read before the fixture closes them, and a context kept for the whole worker follows the current test’s identity. Actions on such pages are not recorded as separate phases, so their evidence is attributed to the test and its assertions rather than to individual clicks.

Node child processes inherit coverage automatically. Long-running servers get a short drain window after the test command finishes so buffered evidence can arrive. Work without a reliable test identity is kept as background coverage instead of being assigned to an arbitrary test.

A child a test stops in teardown keeps the coverage it produced. Buffered evidence is written when a terminating signal arrives—SIGTERM, SIGINT, SIGHUP—not only when the process exits on its own, so killing a gateway after the request it served does not lose the request. The program’s own signal handling is untouched: a process with no handler still dies from the signal exactly as it would unmeasured, and one with its own handler keeps it. SIGKILL cannot be caught by anything and is the one stop that loses whatever was still buffered.

Rust

RunnerAttributionCurrent requirement
Cargo’s standard libtest runnerExact test, attempt, and passing-assertion identityRust 1.95; run with supercov -- cargo test
rustdoc doctestsExact doctest identity; every doctest runs in a process of its ownRust 1.95; part of supercov -- cargo test
cargo-nextestExact test, attempt, retry, and binary identitycargo-nextest 0.9.138 or 0.9.140

Supercov preserves Cargo’s test selection, scheduling, fail-fast behavior, environment and exit status. Doctests run with their own identities; nextest retries remain separate attempts.

Measured source follows the modules rustc compiles, including #[path] and literal include! calls. Undeclared .rs files are not treated as application modules. Statements, functions, branches, boolean decisions, loops and error propagation are measured. Const contexts and macro expansions remain visible with explicit measurement limitations.

Use the repository’s normal flags after the wrapped command:

supercov -- cargo test --workspace
supercov -- cargo nextest run --workspace

cross is not supported yet. Unsupported command shapes fail with an explanation instead of silently falling back to plausible but inaccurate attribution.

Python

RunnerAttributionCurrent requirement
pytestExact test, worker, retry, and setup/call/teardown phase identityCPython 3.12 or newer; run with uvx --from supercov-cli supercov -- pytest or python -m pytest
pytest-xdistExact per workerWorkers inherit the run through the environment
pytest-rerunfailuresExact per attempt; flaky tests are reported as such
python -m unittestExact test and setUp/test/tearDown phase identitySerial in-process; skips and expected failures are recorded; subtest failures roll up to the parent test

Your project runs in place with its own interpreter and virtual environment. Supercov adds its monitoring and runner hooks through the process environment; you do not need to rewrite tests or configure a different build.

Coverage includes statements, functions, boolean decisions, loops, comprehensions, short-circuit operators, match cases and exception paths. Child interpreters, threads and thread pools can retain the calling test’s identity. The report also distinguishes execution before a passing assertion from later execution. These phase records alone do not prove which values the assertion checks.

Interpreters launched with -I, -E or -S ignore the required startup hook and are not measured. Code compiled from strings at runtime has no source obligations. Completed observations can survive a hard kill, but a corrupt or exhausted evidence channel fails the run rather than reporting partial data as complete.

uvx --from supercov-cli supercov -- pytest
uvx --from supercov-cli supercov -- python -m pytest -n 4
uvx --from supercov-cli supercov -- uv run pytest
uvx --from supercov-cli supercov -- python -m unittest

Ruby

RunnerAttributionCurrent requirement
RSpecExact example and before/example/after phase identityRuby 3.4 or newer for full measurement; run with supercov -- rspec or bundle exec rspec
Minitest (including Minitest::Spec and ActiveSupport::TestCase)Exact test and setup/test/teardown identity; skips recordedruby -Itest ..., rake test, rails test
test-unitExact test and setup/test/teardown identity; omissions and pendings recordedruby -Itest ..., rake test
parallel_tests, Rails process workersExact per worker processWorkers inherit the run through RUBYOPT; verified on a Rails app with bootsnap, Zeitwerk and two forked workers
Thread-parallel Minitest (parallelize_me!, parallelize(with: :threads))Probe observations exact per test; line, method and simple-branch observations made while phases overlapped go to the run, declared
CucumberExact scenario identity (features/x.feature:LINE), hook steps as setup/teardowncucumber, bundle exec cucumber

Your project runs in place with its own interpreter and bundle. Supercov loads through RUBYOPT; application files on disk and their backtrace line numbers stay unchanged. RSpec, Minitest and test-unit assertions can identify execution before a passing assertion. That timing evidence alone does not show which values the assertion checks.

Ruby 3.4 and newer support statement, method, branch and MC/DC measurement, including loops, iterator blocks, short-circuit operators, pattern matching, optional calls and exception paths. Ruby 3.3 supplies Ruby’s own line, method and branch coverage; obligations requiring additional instrumentation are reported as measurement limits.

Some constructs have narrower coverage. Code in a non-main Ractor keeps line coverage but may lack other observations. Certain nested-return expressions limit normal-completion measurement. Constant predicates are folded as Ruby folds them, so unreachable alternatives do not become obligations.

If a file cannot be instrumented safely, Supercov loads it unchanged and reports the remaining limits. To apply that fallback to a known incompatible file, set SUPERCOV_RUBY_SKIP_PROBES to a comma-separated list of path fragments. This reduces measurement; it is not a way to claim that skipped obligations are covered.

A Spring preloader started before the run has no coverage hook. Restart it within the measured command. JRuby and TruffleRuby are not supported.

Stop test-owned Ruby servers with SIGTERM or wait for normal exit so they can report their evidence. SIGKILL and exit! can lose observations since the last test boundary. A process that does not report leaves a measurement limit; its missing evidence is not counted as uncovered application code.

supercov -- rspec
supercov -- bundle exec rspec
supercov -- ruby -Itest test/shapes_test.rb
supercov -- bin/rails test

Containers, VMs, and remote execution

Supercov can collect from supported processes launched through a container, VM, or remote executor when it can see the launch boundary, carry the instrumented workspace into that environment, and receive evidence back.

Mounted workspaces and local child-process launchers are the most direct path. If an executor hides how code is launched or cannot return evidence, Supercov reports the missing boundary rather than claiming unseen code was measured.

If your runner is not listed

For a Node-based runner, try the complete command and inspect the result:

npx supercov -- npm test
npx supercov runs latest runners
npx supercov runs latest scope

Aggregate coverage may already be useful even without exact per-test identity. If a supported runner appears incomplete, see Troubleshooting and include the exact command and runner output when opening an issue.