coverage
- Type:
- Default:
undefined
Collect code coverage and generate coverage reports.
Options
enabled
- Type:
boolean - Default:
false - CLI:
--coverage,--coverage=false,--no-coverage
Enable or disable test coverage collection.
provider
- Type:
'istanbul' | 'v8' - Default:
'istanbul' - CLI:
--coverage.provider <provider>
The coverage provider to use. Rstest supports both istanbul and v8. Choose istanbul when you want SWC-based instrumentation performance and stable Istanbul semantics. Choose v8 when coverage is mainly limited by memory pressure; it usually has lower runtime memory usage because it does not inject coverage counters into every executed module.
Istanbul provider
Istanbul is a widely used JavaScript code coverage tool that collects coverage through instrumentation.
To enable istanbul coverage, install @rstest/coverage-istanbul first.
@rstest/coverage-istanbul is powered by swc-plugin-coverage-instrument. Rstest instruments source files through SWC during transform, so this provider has good transform-time performance. It can use more runtime memory because executed modules keep the injected coverage counters.
Excluding code
Use coverage.exclude when a whole file, generated file group, or injected script should not be instrumented:
You can also pass the same patterns from the CLI for a one-off run:
Use Istanbul ignore comments only for small snippets that must stay in an otherwise covered file:
If an ignored snippet still receives an injected cov_* call, use coverage.exclude for the source file instead.
Serialized functions and other realms
Istanbul injects cov_* coverage counter calls into instrumented files. Those counters are scoped to the transformed module that Rstest executes. If code from an instrumented file is serialized and executed somewhere else, the new scope or realm may not have the matching cov_* helper, and the test can fail with ReferenceError: cov_... is not defined.
This can happen when a function is serialized with fn.toString() or executed through APIs such as page.evaluate, Worker, node:vm, eval, or new Function.
To avoid the failure, prefer one of these approaches:
- exclude the source file with
coverage.exclude; - switch to
coverage.provider: 'v8'for non-browser tests; - avoid serializing Istanbul-instrumented functions.
The v8 provider is not available in Browser Mode, so browser tests should use coverage.exclude or avoid serializing instrumented functions.
V8 provider
The v8 provider collects precise coverage from the Node.js inspector, then remaps it to Istanbul format. Compared with Istanbul instrumentation, V8 coverage usually has lower runtime memory usage because executed modules do not need extra coverage counters. It is a better fit for large non-browser test suites where coverage memory pressure is the bottleneck.
To enable V8 coverage, install @rstest/coverage-v8 first.
Because the underlying coverage data comes from Node.js / V8 itself, remapped branch coverage and uncovered line details can vary slightly across different Node.js or V8 versions.
Ignore hints
The v8 provider honors ignore hints when converting V8 coverage to Istanbul format. The hint prefix can be any of the following forms:
Prefer using one prefix consistently in a project. The supported hint forms are:
ignore file is also recognized, but it applies to the generated coverage entry before source-map remapping. In normal Rstest output, one generated chunk can contain multiple source files, so prefer coverage.exclude when a source file or generated file group should be excluded.
The v8 provider is only available outside Browser Mode, including node, jsdom, and happy-dom test environments. Browser Mode does not use inspector coverage, so browser coverage should use the default istanbul provider.
include
- Type:
string[] - Default:
undefined - CLI:
--coverage.include <pattern>
A list of glob patterns that should be included for coverage collection. Repeat the CLI flag to specify multiple patterns.
By default, rstest will only collect coverage for files that are tested. If you want to include untested files in the coverage report, you can use the include option to specify the files or patterns to include.
Note that you should use standard glob syntax here. For a single extension, write src/**/*.ts instead of src/**/*.{ts}. Single-value braces are treated literally by the underlying glob libraries, so src/**/*.{ts} will not match .ts files.
changed
- Type:
boolean | string - Default:
undefined - CLI:
--coverage.changed,--coverage.changed=<commit>
Collect coverage only for files changed in the current Git repository. Pass a commit or branch to collect coverage for files changed since that ref.
This option is available in both config and CLI:
- Use
coverage.changedinrstest.config.tswhen you want a persistent default, for example in CI. - Use
--coverage.changedfor one-off local or CI runs.
coverage.changed only limits the coverage report scope. It does not change which tests are executed.
That means these two commands do different things:
--changedchanges the test selection and runs tests related to changed files.--coverage.changedkeeps the normal test selection, but only reports coverage for changed source files.
Interaction with --changed
- When
--changedis used andcoverage.changedis not configured, coverage reports inherit the changed files collected by--changed. - If
--changedhitsforceRerunTriggers, Rstest reruns the full test suite. Coverage stays full in that case unlesscoverage.changedis explicitly enabled. - If you want to use
--changedfor test selection but still keep full coverage reports, setcoverage.changedtofalsein config.
Common setups:
The example above still runs the normal test suite, but the coverage report only includes files changed since origin/main.
npx rstest run --changed --coverageruns changed-related tests and, by default, also limits coverage to the same changed file set.npx rstest run --coverage.changed=HEAD~1runs the normal test suite but only reports coverage for files changed sinceHEAD~1.npx rstest run --coverage.changed=origin/mainis useful when your branch is based onmain: it still runs the normal test suite, but the coverage report only includes files changed compared withorigin/main.
exclude
- Type:
string[] - CLI:
--coverage.exclude <pattern> - Default:
A glob pattern array to exclude files from test coverage collection. Repeat the CLI flag to specify multiple patterns.
Any patterns specified here will be merged with default values.
Rstest does not exclude directories named test by default. This avoids accidentally dropping source files from packages or workspaces whose path contains a test segment, such as packages/test/src/index.ts. To exclude those directories from coverage, add an explicit pattern such as test/** or **/test/**.
reporters
- Type:
CoverageReporter[] - Default:
['text', 'html', 'clover', 'json'] - CLI:
--coverage.reporters <reporter>
The reporters to use for coverage collection. Rstest uses the standard Istanbul reporter API instead of a Rstest-specific coverage reporter API.
Each reporter can be either a string (the reporter name), a tuple with the reporter name and its options, or an Istanbul-compatible reporter object with an execute(context) method.
The CLI supports reporter names only. Repeat the flag to specify multiple reporters:
- See Istanbul Reporters for available reporters.
- See @types/istanbul-reports for details about reporter specific options.
Custom coverage reporters
Custom coverage reporters should follow the Istanbul reporter contract. A reporter package or file is loaded by Rstest's coverage provider (using istanbul-reports when possible), constructed with the options from coverage.reporters, and then called with an Istanbul report context.
For example, an ESM reporter can export a class with an execute method. The context parameter is Istanbul's Context type from istanbul-lib-report:
Then reference the reporter by package name or file path in rstest.config.ts:
You can also pass an Istanbul-compatible reporter object directly when the reporter is created in config:
reportsDirectory
- Type:
string - Default:
'./coverage' - CLI:
--coverage.reportsDirectory <dir>
The directory to store coverage reports.
reportOnFailure
- Type:
boolean - Default:
false - CLI:
--coverage.reportOnFailure
Whether to report coverage and check thresholds when tests fail.
allowExternal
- Type:
boolean - Default:
false - CLI:
--coverage.allowExternal
Whether to collect coverage for source files outside the project root directory. This is useful in monorepo setups where tests import modules from sibling packages.
By default, rstest excludes files outside the project root from coverage reports, which aligns with the behavior of Jest and Vitest.
clean
- Type:
boolean - Default:
true - CLI:
--coverage.clean,--coverage.clean=false
Whether to clean the coverage directory before running tests.
thresholds
- Type:
- Default:
undefined
Coverage thresholds for enforcing minimum coverage requirements. You can set thresholds for statements, functions, branches, and lines.
Thresholds specified as a positive number are taken to be the minimum percentage required. Thresholds specified as a negative number represent the maximum number of uncovered entities allowed.
When the code coverage is below the specified thresholds, the test will fail and output an error message like below:
glob pattern
If globs are specified, thresholds will be checked for each matched file pattern. If the file specified by path is not found, an error is returned.
Following the above configuration, rstest will fail if:
- The total code coverage of all files in
src/**is below 100%. - The total code coverage of all files in
node/**/*.jsis below 90%. - The global code coverage is below 80% for statements.
check threshold for per file
Rstest also supports checking thresholds for each matched file by setting perFile to true.