@storybook/test: more streamlined and powerful testing

Storybook is the best way to build and test your UI components in isolation. Storybook 7.6 (now in alpha) takes Storybook's testing even further with the introduction of @storybook/test. It brings a set of new utilities for spying on your components, interacting with them in the browser, and asserting the results. Plus better performance and smaller size.

The new hotness

@storybook/test consolidates the API of @storybook/jest and @storybook/testing-library into a new, single package. However, the expect and spy utilities are now powered by Vitest. This streamlines the package and reduces its size. It also brings new testing patterns that quicken load times and increase the ease of reusing stories in different test systems, like Jest, Vitest, and Playwright/Cypress.

The package exports instrumented version of:

This ensures sure you can debug these methods in Storybook using addon-interactions.

A visualization of testing a form in Storybook, using storybook/test

Question: What's happening to the @storybook/jest package? And does this mean I can now use Vitest in Storybook?

@storybook/test exports an expect utility with the same API as @storybook/jest, but it is now powered by Vitest. You can also import a couple of other Vitest utilties coming from the @vitest/spy package:

import {expect, fn, spyOn, isMockFunction, spies } from '@storybook/test'

Please note that @storybook/test doesn’t bring Vitest into the Storybook test runner. We are only utilizing a couple of Vitest’s internal utilities, so that you can use those in your stories.

Explicit action args

We're also introducing a new pattern for writing actions/spies in Storybook. Instead of using automated 'docgen' analysis to create function mocks in Storybook, we now advocate for you to explicitly mock actions with spies.

import { Button } from './Button';
import { fn } from '@storybook/test';

export default {
  component: Button,
  args: {
    onClick: fn(),
  },
};

Our goal is to make story rendering independent from docgen. That's because depending on docgen analysis makes stories slower and less portable. Resolving this requires a little more code than before but brings significant benefits.

For example: in the past, the results of the play function below would change depending on whether you used docgen. Results can even be influenced by the type of docgen you use (e.g. react-docgen vs react-docgen-typescript).

import { within, userEvent, expect, fn } from '@storybook/test';

export const Primary = {
  play: async ({ args, canvasElement }) => {
    const canvas = within(canvasElement);
    await userEvent.click(canvas.getByRole('button'));
    await expect(args.onClick).toHaveBeenCalled();
  },
};

Explicit actions ensure sure that the play function produces consistent results. It allows users and integrators to run/build Storybook without docgen, boosting user performance and feedback times. Plus, it lets TypeScript understand the type of spy.

Screenshot of TypeScript understanding spy type in a code block

Learn more about the motivation around writing ‘explicit’ actions in this RFC:

[RFC] Explicit Actions Args Mocking · storybookjs/storybook · Discussion #23649
Status: accepted; championed by @kasperpeulen 🖼️ Overview Outcome We want a CSF story to render the same no matter if argTypes inference (which requires docgen provided by addon-docs) is available…

Installation

You can try @storybook/test today. The package is available in the latest alpha version of Storybook. Add it by installing Storybook from the the next tag.

# Upgrade your storybook
npx storybook@next upgrade --prerelease

# Install the addon with your package manager
npm install -D @storybook/test@next
pnpm add -D @storybook/test@next
yarn add -D @storybook/test@next

Then, update your stories.

- import { expect } from '@storybook/jest';
- import { within, userEvent } from '@storybook/testing-library';
+ import { within, userEvent, expect, fn } from '@storybook/test';

Note: this package is not an addon, it is just a collection of utilities. As such, you don't need to add it to your main.ts/js file.

Interested in learning more about testing with Storybook? Check out a fantastic new blog by Storybook maintainer Ian VanSchooten, exploring how he and his team test their frontend apps.


Other news from last month

Chromatic Visual Tests addon enters private beta

Demonstration of the addon workflow

You can take your Storybook's testing capabilities even further with the Chromatic Visual Test addon, now in beta. The addon lets you run Chromatic visual tests inside the Storybook addon panel. Spin up tests, view results, and see diffs right beside your stories.

Sign up for early access and join over 900 early adopters bringing visual testing into their Storybooks. Sign up here.

New launch: Storybook 7.5

Storybook 7.5 arrived. The latest release brings a ton of new changes for all our users. Including 2.2x faster React+TS load times, Angular improvements, Vite 5.0 and Lit 3.0 support, and much more. Check out the full list of what’s in 7.5.

Coming soon: Storybook 7.6

All aboard the releases trains. Next stop: Storybook 7.6! The next minor release is well on the way, and the first prerelease launches are already here. Take a look. We’ll have more to share on this one soon.

Improved NextJS support

Storybook and NextJS, integrated as jigsaw puzzle pieces

Finally, last month carried several improvements for our NextJS users. We synced up Storybook to Next 14. Thanks to Nikos Papageorgiou for the PR. We also added support for the avif image format and fixed how Storybook forwards the ref property for Next Image components.

That's all for this month's roundup. Look forward to more Storybook content coming your way very soon.