Test Coverage and CI

Purpose and Scope

Test coverage is the Storybook testing workflow for answering a practical question: do the stories and component tests exercise the important code paths in a UI component? The coverage documentation defines coverage as measurement over conditions, logic branches, functions, and variables, and frames the report as a final quality signal for the test suite rather than as a replacement for writing good stories. In Storybook projects, coverage is especially useful because stories already model component states, so the report can identify which visible states have meaningful test execution and which branches remain untested.

Sources: docs/writing-tests/test-coverage.mdx

The page is centered on projects using Storybook Test through the Vitest addon. Coverage is described as part of the Vitest addon workflow: when enabled, component tests run against tested stories and produce a report that is summarized in the Storybook testing widget. The documentation also preserves an alternate route for projects that cannot use the Vitest addon: generate coverage through the test-runner following the test-runner coverage instructions. That distinction matters for CI planning because the same team may use the interactive UI locally while relying on a command-line runner in automation.

Sources: docs/writing-tests/test-coverage.mdx

Relevant Source Files

  • docs/writing-tests/test-coverage.mdx — defines the test coverage concept, explains the Vitest addon setup and UI workflow, documents report access at /coverage/index.html, lists coverage limitations, and introduces the Vitest CLI path for generating reports.

Core Primitives

The first primitive is the coverage report itself. The documentation tells readers to inspect both the overall line or branch coverage and the specific uncovered lines or branches. The overall number is a health check: it helps decide whether the current suite is trending in the right direction. The uncovered locations are the actionable part: they point to component states, conditional rendering paths, event handlers, or utility branches that may need additional stories, play functions, or assertions.

Sources: docs/writing-tests/test-coverage.mdx

The second primitive is the Storybook testing widget. With the Vitest addon installed, coverage can be enabled from the widget by checking the coverage checkbox. After tests run, the widget summarizes statement coverage and indicates whether the result meets configured watermarks. This gives developers a local, visual feedback loop: enable coverage, run the project’s component tests, inspect the summary, and drill into the full report when the aggregate percentage hides specific untested code.

Sources: docs/writing-tests/test-coverage.mdx

The third primitive is the generated HTML report served by the running Storybook at /coverage/index.html. The documentation emphasizes that the report is interactive: developers can navigate into a component’s source and see what is covered and uncovered. That makes coverage useful during authoring, not only at the end of a pipeline. Instead of treating coverage as a single failing number, a team can use the report to discover which story states or interaction flows should be added next.

Sources: docs/writing-tests/test-coverage.mdx

Set Up Coverage

Coverage is included in the Vitest addon and is calculated when component tests run with coverage enabled. Before a project can calculate coverage, it may need a support package matching the configured coverage provider; the docs include a reusable code-snippet include for installing those provider packages. The setup sequence is therefore: use the Vitest addon for Storybook Test, install any required provider support, enable the coverage checkbox in the testing widget, and run the component tests for the project.

Sources: docs/writing-tests/test-coverage.mdx

A typical package script for command-line execution uses Vitest’s Storybook project selection. The documented example names the script test-storybook and runs vitest --project=storybook. That shape is important because coverage is not a separate Storybook-only runner in this flow; it is built on Vitest. In local development, the UI gives a richer review experience. In automation, the CLI gives a repeatable command that can be run without manually interacting with the Storybook UI.

{
  "scripts": {
    "test-storybook": "vitest --project=storybook"
  }
}

Sources: docs/writing-tests/test-coverage.mdx

Execution Flow

The local execution flow starts with stories. Storybook’s testing documentation treats stories as test cases for component states and configurations, and the coverage page narrows that idea to the instrumented code reached by those tests. Once coverage is enabled, the Vitest addon runs component tests across the project’s stories and computes statement coverage. The testing widget then presents the percentage, while the full report gives file-level detail. This keeps the feedback loop close to the component explorer where authors are already building and debugging states.

Sources: docs/writing-tests/test-coverage.mdx

For CI, the practical pattern is to promote the same Vitest project command used locally into a package script and run that script in the pipeline. The key is consistency: CI should execute the Storybook component-test project that developers can also run on their machines, then archive or publish the generated coverage artifacts according to the team’s coverage provider and CI service. Because the docs state that coverage is built on top of Vitest, teams should use Vitest’s CLI coverage options and reporting behavior around the Storybook project command rather than inventing a separate Storybook coverage invocation.

Sources: docs/writing-tests/test-coverage.mdx

Limitations and CI Implications

The documentation calls out three limitations that should shape expectations. First, Storybook UI coverage is calculated from the stories that have been written, not from the entire codebase, and it does not include other Vitest tests. Second, coverage is calculated for all stories in the project rather than for one story or one group of stories. Third, coverage is not calculated while watch mode is active; enabling watch mode disables coverage when coverage is enabled. These constraints are not incidental details: they determine what coverage can safely mean in a status check.

Sources: docs/writing-tests/test-coverage.mdx

In CI, those limits mean a Storybook coverage job should be described as coverage for Storybook component tests, not total repository coverage unless the team intentionally merges it with other reports. Teams should avoid treating a single Storybook coverage percentage as proof that unrelated utilities, services, or non-story Vitest tests are covered. They should also run coverage in a non-watch command, because watch mode is explicitly incompatible with coverage calculation. If a repository has separate unit, integration, and Storybook test suites, the CI dashboard should label the reports clearly or combine them through a coverage service outside Storybook.

Sources: docs/writing-tests/test-coverage.mdx

Compact Reference

SurfaceWhat it doesSource-backed behavior
Testing widget coverage checkboxEnables coverage for Storybook Test through the Vitest addonGenerates a summary after tests run and shows statement coverage plus watermark status
/coverage/index.htmlServes the full generated report from a running StorybookLets developers click into component source and inspect covered and uncovered code
vitest --project=storybookRuns the Storybook Vitest project from the CLIProvides the documented command shape for package scripts and CI jobs
Test-runner coverage pathAlternate coverage route when the Vitest addon cannot be usedDelegates setup to the test-runner coverage documentation

Sources: docs/writing-tests/test-coverage.mdx

Next Steps

Start by enabling coverage locally in the Storybook testing widget and reviewing both the summary and the interactive report. Add or improve stories where uncovered branches correspond to meaningful component states, then move the stable command into CI using a package script such as test-storybook. If your project cannot use the Vitest addon, follow the test-runner coverage route instead. For the surrounding workflow, read the interaction testing and accessibility testing pages next so coverage is paired with meaningful assertions and user-facing quality checks.