Test runner with Vitest
(โ ๏ธ Experimental)
While this feature is experimental, it is published as the @storybook/experimental-addon-vitest
package.
Storybook's test runner with Vitest transforms your stories into tests using a Vitest plugin and portable stories. Those tests are then run using Vitest. This approach is faster and more flexible than the previous test runner, which required a running Storybook instance to test your stories.
We recommend (and configure, by default) running Vitest in browser mode, using Playwright's Chromium browser. Browser mode ensures your components are tested in a real browser environment, which is more accurate than simulations like JSDom or HappyDom. This is especially important for testing components that rely on browser APIs or features.
Stories are tested in two ways: a smoke test to ensure it renders and, if a play function is defined, that function is run and any assertions made within it are validated.
Install and set up
Get started by upgrading to at least Storybook 8.3, then installing and configuring the plugin in your project.
Automatic setup
Run the following command to install and configure the addon, which contains the plugin to run your stories as tests using Vitest:
That add
command will install and register the Vitest addon. It will also inspect your project's Vite and Vitest setup, and install and configure them with sensible defaults, if necessary. You may need to adjust the configuration to fit your project's needs. The full configuration options can be found in the API section, below.
Manual setup
For some project setups, the add
command may be unable to automate the plugin setup and ask you to complete additional setup steps. Here's what to do:
- Make sure Vite and Vitest are configured in your project.
- Configure Vitest to use browser mode.
- Install the addon,
@storybook/experimental-addon-vitest
, in your project and register it in your Storybook configuration. - If you're using Next.js, make sure you're using
vite-plugin-storybook-nextjs
. - If you're using SvelteKit, make sure you're using
@storybook/sveltekit/vite
. - Create a test setup file,
.storybook/vitest.setup.ts
. - Adjust your Vitest configuration to include the plugin(s) and reference the setup file. You can use the example configuration files, below, as a guide.
Example configuration files
When the addon is set up automatically, it will create or adjust your Vitest configuration files for you. If you're setting up manually, you can use the following examples as a reference when configuring your project.
Example Vitest setup file
Example Vitest config file
Example Vitest workspace file
Usage
There are three primary ways to run tests using the Vitest plugin:
CLI
The plugin transforms your stories into real Vitest tests, so you run those tests just like you run any other Vitest tests in your project. Typically, you will have a test
script in your package.json
that runs your tests.
If you don't already have a test
script, you can add one that runs Vitest:
If you already have a test
script that runs something other than Vitest, you can either adjust it to run Vitest (as above) or add a new script that runs Vitest:
When you run that script, the addon will find and run your story-based tests. Here's an example of running your tests (in watch mode, by default) using the Vitest CLI:
Editor extension
Transforming your stories into Vitest tests with the plugin also enables you to run and debug tests using Vitest IDE integrations. This allows you to run tests directly from your editor, such as VSCode and JetBrains IDE.
[TK - Screenshot of VS Code]
In CI
For the most part, running your Storybook tests in CI is done via the CLI. However, to have the test output link to your published Storybook on test failures, you need to provide the storybookUrl
option in the plugin configuration.
Here's an example using GitHub Actions. The steps are similar for other CI providers, though details in the syntax or configuration may vary.
When actions for services like Vercel, Netlify and others run a deployment job, they follow a pattern of emitting a deployment_status
event containing the newly generated URL under deployment_status.target_url
. This is the URL to the published Storybook instance. We then pass that URL to the plugin configuration using an environment variable, SB_URL
. Finally, we update the plugin configuration to use that environment variable in the storybookUrl
option.
Debugging
While the plugin does not require Storybook to run when testing, you may still want to run Storybook to debug your tests. To enable this, provide the storybookScript
option in the plugin configuration. When you run Vitest in watch mode, the plugin will start Storybook using this script and provide links to the story in the output on test failures. This allows you to quickly jump to the story in Storybook to debug the issue.
You can also provide a storybookUrl
option to the plugin configuration. When you're not using watch mode and tests fail, the plugin will provide a link to the story using this URL in the output. This is useful when running tests in CI or other environments where Storybook is not already running.
[TK - Screenshot of test output with links to SB]
Configuration
Most of the configuration for the Vitest plugin's behavior is done in the Vitest configuration files. However, you can also define configuration in your stories themselves, using tags, to control how they are tested.
By default, the plugin will run all stories with the test
tag. You can adjust this behavior by providing the tags
option in the plugin configuration. This allows you to include, exclude, or skip stories based on their tags.
In this example, we'll apply the stable
tag to all of the Button component's stories, except for ExperimentalFeatureStory, which will have the experimental
tag:
To connect those tags to our test behavior, we can adjust the plugin configuration to exclude the experimental
tag:
If the same tag is in both the include
and exclude
arrays, the exclude
behavior takes precedence.
FAQ
How do I debug my tests in Storybook?
The plugin will attempt to provide links to the story in Storybook when tests fail, for debugging purposes.
If the URLs are not working when running tests in watch mode, you should check two configuration options:
storybookUrl
: Ensure this URL is correct and accessible. For example, the default ishttp://localhost:6006
, which may not use the same port number you're using.storybookScript
: Ensure this script is correctly starting Storybook.
If the URLs are not working when running tests in CI, you should ensure the Storybook is built and published before running the tests. You can then provide the URL to the published Storybook using the storybookUrl
option. See the In CI section for an example.
How do I ensure my tests can find assets in the public directory?
If your stories use assets in the public directory and you're not using the default public directory location (public
), you need to adjust the Vitest configuration to include the public directory. You can do this by providing the publicDir
option in the Vitest configuration file.
How do I apply custom Vite configuration?
If you have custom operations defined in viteFinal
in your .storybook/main.js|ts
file, you will need to translate those into the Vitest configuration. This is because the plugin does not use the Storybook Vite configuration.
How do I isolate Storybook tests from others?
Some projects might contain a test
property in their Vite configuration. Because the Vitest configuration used by this plugin extends that Vite config, the test
properties are merged. This lack of isolation can cause issues with your Storybook tests.
To isolate your Storybook tests from other tests, you need to move the test
property from your Vite configuration to the Vitest configuration. The Vitest config used by the plugin can then safely extend your Vite config without merging the test
property.
Why do we recommend browser mode?
Vitest's browser mode runs your tests in a real browser (Chromium, via Playwright, in the default configuration). The alternative is a simulated browser environment, like JSDom or HappyDom, which can have differences in behavior compared to a real browser. For UI components, which can often depend on browser APIs or features, running tests in a real browser is more accurate.
For more, see Vitest's guide on using browser mode effectively.
How do I use WebDriver instead of Playwright?
We recommend running tests in a browser using Playwright, but you can use WebDriverIO instead. To do so, you need to adjust the browser provider in the Vitest configuration file.
How do I use a browser other than Chromium
We recommend using Chromium, because it is most likely to best match the experience of a majority of your users. However, you can use other browsers by adjusting the browser name in the Vitest configuration file. Note that Playwright and WebDriverIO support different browsers.
How is this different from the previous test runner?
The previous test runner requires a running Storybook instance to test your stories, because it visits each one, executes the play function, and listens for results. This plugin, however, transforms your stories into tests using Vite and portable stories, so it does not need to run Storybook to test your stories. Beyond that core difference, there are a few other distinctions:
Additionally, the previous test runner ran your stories as orchestrated tests in Jest, and that orchestration came with some complexity. By comparison, this plugin transforms your stories into real tests and then runs them using Vitest, which is simpler and more configurable.
Finally, because of the simpler architecture and the use of Vitest, this plugin should be faster than the previous test runner for most projects. We'll do more benchmarking to quantify this in the future.
API
Exports
This addon contributes the following exports to Storybook:
storybookTest
Type: function
A Vitest plugin that transforms your stories into tests. It accepts an options object for configuration.
Options
The plugin is configured using an options object. Here are the available properties:
configDir
Type: string
Default: .storybook
The directory where the Storybook configuration is located, relative to the current working directory.
If your Storybook configuration is not in the default location, you must specify the location here so the plugin can function correctly.
storybookScript
Type: string
Optional script to run Storybook. If provided, Vitest will start Storybook using this script when run in watch mode. Only runs if the Storybook in storybookUrl
is not already available.
storybookUrl
Type: string
Default: http://localhost:6006
The URL where Storybook is hosted. This is used for internal checks and to provide a link to the story in the test output on failures.
tags
Type:
Default:
Tags to include, exclude, or skip. These tags are defined as annotations in your story, meta, or preview.
include
: Stories with these tags will be testedexclude
: Stories with these tags will not be tested, and will not be counted in the test resultsskip
: Stories with these tags will not be tested, and will be counted in the test results