Writing Tests Overview
Purpose and Scope
Storybook treats stories as more than examples for a component catalog. A story captures a UI component in a specific state and configuration, which makes it a natural test case for development, debugging, regression checks, and collaboration. The testing documentation positions this as a holistic workflow: developers build UI in isolation, exercise the rendered result in a browser, reuse the same states across tools, and move those checks into continuous integration. This overview explains how the testing pieces relate so you can choose the right entry point before going deeper into interaction, accessibility, visual, snapshot, coverage, CI, and integration guides.
Sources: docs/writing-tests/index.mdx
The default path for projects that use Vite is Storybook Test through the Vitest addon. That addon installs and configures Vitest so stories can be transformed into real browser-mode tests, then surfaced in Storybook with a testing widget, status indicators in the sidebar, and debugging panels. Projects that cannot use the Vitest addon still have a supported automation path through the test-runner documentation. The important decision is not whether stories should participate in tests, but which runner best fits the project’s framework, builder, and CI constraints.
Sources: docs/writing-tests/index.mdx, docs/writing-tests/in-ci.mdx
Relevant Source Files
- docs/writing-tests/index.mdx — Main testing overview, including the story-as-test-case model, Vitest addon setup, component-test definition, watch mode, CI motivation, and the fallback test-runner path.
- docs/writing-tests/in-ci.mdx — CI guide showing the package script, provider workflow examples, Playwright container recommendation, and the relationship between local Vitest commands and CI execution.
- docs/writing-tests/accessibility-testing.mdx — Accessibility testing guide covering the a11y addon, axe-core foundation, violation reporting, Vitest addon integration, and configuration surface.
- docs/writing-tests/integrations/index.mdx — Integrations landing page for the testing section.
- docs/writing-tests/integrations/stories-in-end-to-end-tests.mdx — Integration guide for reusing CSF stories in Cypress and Playwright end-to-end tests against Storybook’s isolated iframe.
- docs/writing-tests/integrations/stories-in-unit-tests.mdx — Integration guide for reusing stories in Jest, Testing Library, Vitest, and Playwright through portable stories utilities such as composeStories and composeStory.
Core Testing Primitives
A component test in Storybook combines several qualities that are usually split across separate test categories. It renders the component in a real browser for high fidelity, simulates user behavior like an end-to-end test, and still focuses on a single unit of UI with the ability to mock implementation details or manipulate data like a unit test. This definition matters because Storybook’s test experience is built around the same rendered stories developers already use during component development, so each story can serve as documentation, a playground state, and a test scenario.
Sources: docs/writing-tests/index.mdx
The play function is the bridge from static component state to scripted behavior. The end-to-end integration guide describes it as code that runs after a story renders, allowing authors to sequence interactions in the story itself. When that story is reused in Cypress, Playwright, or Storybook Test, the initial state and interaction intent travel with the story instead of being duplicated in each test suite. That reuse lowers maintenance cost because the component state is authored once in Component Story Format and consumed by multiple tools.
Sources: docs/writing-tests/integrations/stories-in-end-to-end-tests.mdx
Portable stories are the reuse model for unit-style tests outside the Storybook UI. The unit-test integration page explains that stories are standard JavaScript modules and that each named export is renderable in a test setup. The composeStories utility converts story exports into renderable elements for Node tests with JSDOM, while composeStory targets a single story. The same page also calls out project annotations, decorators, args, parameters, and global configuration as features that need to be applied so the test environment stays aligned with the Storybook environment.
Sources: docs/writing-tests/integrations/stories-in-unit-tests.mdx
Recommended Execution Flow
Start by authoring useful stories for the component states you care about: valid, invalid, loading, empty, permission-constrained, responsive, or otherwise meaningful variations. Once those states exist, use the Vitest addon when your project can run it, especially in Vite-based setups. The installation command referenced by the docs installs and configures both the addon and Vitest, after which the Storybook UI gains a testing widget at the bottom of the sidebar. After test execution, status indicators appear beside stories and debugging information can be inspected in addon panels.
Sources: docs/writing-tests/index.mdx
During local development, watch mode gives immediate feedback as the component source or related tests change. The docs frame it as especially useful for test-driven development because only the relevant tests rerun after changes. This is a useful mental model for teams adopting Storybook Test: the Storybook sidebar remains the navigational surface for component states, while Vitest provides the execution engine. Developers can inspect failures close to the rendered story instead of switching only to a terminal output or a separate browser automation report.
Sources: docs/writing-tests/index.mdx
When adding accessibility checks, install the Accessibility addon and use it while navigating stories. The addon is built on axe-core, reports automated checks in an Accessibility panel, and separates findings into violations, passes, and incomplete checks that need manual confirmation. It also adds a toolbar control for simulating vision impairments. Because automated accessibility checks catch only a portion of possible issues, the panel is best treated as the first line of quality assurance rather than a complete accessibility certification. The same guide also notes integration with the Vitest addon so accessibility checks can run alongside component tests.
Sources: docs/writing-tests/accessibility-testing.mdx
CI and Automation Model
CI should run the same Storybook tests that developers run locally. The CI guide recommends defining a package script such as a test-storybook command that invokes Vitest with the Storybook project selected. That script is then called from the CI provider workflow. This keeps the automation contract simple: local and CI execution use the same test command, while the CI environment supplies dependency installation, browser support, and pull-request enforcement. If a project cannot use the Vitest addon, the CI guide points readers to the test-runner setup instead of leaving Storybook stories outside automation.
Sources: docs/writing-tests/in-ci.mdx
{
"scripts": {
"test-storybook": "vitest --project=storybook"
}
}The provider examples in the CI guide all follow the same shape: check out the repository, set up Node, install dependencies, and run the Storybook test script. The GitHub Actions example uses a Playwright container image, and the GitLab and Bitbucket examples also highlight using the latest Playwright image for browser execution. That detail is important because Storybook component tests run in a browser context, so CI must provide compatible browser dependencies. Treat the CI file as an environment wrapper around the test script, not as a separate source of testing behavior.
Sources: docs/writing-tests/in-ci.mdx
Integration Patterns
Stories can also feed unit tests. The unit-test integration guide explains the motivation clearly: teams often retest the same UI state in many tools, which creates a maintenance burden when each tool repeats setup manually. By importing stories into Jest, Testing Library, Vitest, or Playwright, teams reuse the states already captured in Storybook. In Testing Library examples, composed stories are rendered in the unit-test renderer and queried with screen helpers. In a story play function, the guide recommends using the provided canvas queries so interactions stay scoped to the rendered story.
Sources: docs/writing-tests/integrations/stories-in-unit-tests.mdx
Stories can feed end-to-end tests as well. The Cypress and Playwright integration guide describes loading Storybook’s isolated iframe, rendering a named story export, and asserting that the UI behaves as expected. A login form example uses the same story with a play function as the basis for both Cypress and Playwright checks. In Cypress, the test loads the isolated iframe and verifies input values. In Playwright, the runner opens a browser, loads the Storybook iframe, asserts that inputs contain the expected values, and reports results in the terminal.
Sources: docs/writing-tests/integrations/stories-in-end-to-end-tests.mdx
These integration paths do not replace Storybook Test; they complement it. Storybook Test is the first-party path for real-time story execution in Storybook through Vitest, while portable stories let teams bring story states into existing unit suites, and iframe-based Cypress or Playwright flows let teams connect stories to broader browser automation. Accessibility testing adds another layer by auditing the rendered DOM against heuristics based on WCAG rules and industry practices. Used together, these layers let teams test behavior, accessibility, visual states, and regression risk without abandoning the story authoring model.
Sources: docs/writing-tests/index.mdx, docs/writing-tests/accessibility-testing.mdx, docs/writing-tests/integrations/stories-in-end-to-end-tests.mdx, docs/writing-tests/integrations/stories-in-unit-tests.mdx
Next Steps
Use this overview as a routing page. If you are starting from scratch on a Vite project, install the Vitest addon and confirm that the testing widget appears in Storybook. If you already have stories with play functions, run them locally in watch mode and then add the CI script so pull requests execute the same checks. If accessibility is a priority, add the a11y addon early so violations appear while components are still being designed. If your organization already relies on Jest, Testing Library, Cypress, or Playwright, reuse stories through the integration guides instead of rewriting component states by hand.
Sources: docs/writing-tests/index.mdx, docs/writing-tests/in-ci.mdx, docs/writing-tests/accessibility-testing.mdx, docs/writing-tests/integrations/stories-in-end-to-end-tests.mdx, docs/writing-tests/integrations/stories-in-unit-tests.mdx