Skip to content

Commit 08b3b66

Browse files
kylegachdummdidummJReinhold
authored
docs: add testing with storybook (#16701)
* docs: add testing with storybook * docs: remove video * docs: address feedback - consistent tabs vs. spaces in snippet - add more Storybook details * Revise Storybook testing documentation condense, remove referer query parameters * Update documentation/docs/07-misc/02-testing.md Co-authored-by: Jeppe Reinhold <[email protected]> * Tweaks - Prose updates - More helpful link * make it its own section --------- Co-authored-by: Simon H <[email protected]> Co-authored-by: Jeppe Reinhold <[email protected]>
1 parent f51c04a commit 08b3b66

File tree

1 file changed

+44
-2
lines changed

1 file changed

+44
-2
lines changed

documentation/docs/07-misc/02-testing.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ export function logger(getValue) {
160160

161161
### Component testing
162162

163-
It is possible to test your components in isolation using Vitest.
163+
It is possible to test your components in isolation, which allows you to render them in a browser (real or simulated), simulate behavior, and make assertions, without spinning up your whole app.
164164

165-
> [!NOTE] Before writing component tests, think about whether you actually need to test the component, or if it's more about the logic _inside_ the component. If so, consider extracting out that logic to test it in isolation, without the overhead of a component
165+
> [!NOTE] Before writing component tests, think about whether you actually need to test the component, or if it's more about the logic _inside_ the component. If so, consider extracting out that logic to test it in isolation, without the overhead of a component.
166166
167167
To get started, install jsdom (a library that shims DOM APIs):
168168

@@ -246,6 +246,48 @@ test('Component', async () => {
246246

247247
When writing component tests that involve two-way bindings, context or snippet props, it's best to create a wrapper component for your specific test and interact with that. `@testing-library/svelte` contains some [examples](https://testing-library.com/docs/svelte-testing-library/example).
248248

249+
### Component testing with Storybook
250+
251+
[Storybook](https://storybook.js.org) is a tool for developing and documenting UI components, and it can also be used to test your components. They're run with Vitest's browser mode, which renders your components in a real browser for the most realistic testing environment.
252+
253+
To get started, first install Storybook ([using Svelte's CLI](/docs/cli/storybook)) in your project via `npx sv add storybook` and choose the recommended configuration that includes testing features. If you're already using Storybook, and for more information on Storybook's testing capabilities, follow the [Storybook testing docs](https://storybook.js.org/docs/writing-tests?renderer=svelte) to get started.
254+
255+
You can create stories for component variations and test interactions with the [play function](https://storybook.js.org/docs/writing-tests/interaction-testing?renderer=svelte#writing-interaction-tests), which allows you to simulate behavior and make assertions using the Testing Library and Vitest APIs. Here's an example of two stories that can be tested, one that renders an empty LoginForm component and one that simulates a user filling out the form:
256+
257+
```svelte
258+
/// file: LoginForm.stories.svelte
259+
<script module>
260+
import { defineMeta } from '@storybook/addon-svelte-csf';
261+
import { expect, fn } from 'storybook/test';
262+
263+
import LoginForm from './LoginForm.svelte';
264+
265+
const { Story } = defineMeta({
266+
component: LoginForm,
267+
args: {
268+
// Pass a mock function to the `onSubmit` prop
269+
onSubmit: fn(),
270+
}
271+
});
272+
</script>
273+
274+
<Story name="Empty Form" />
275+
276+
<Story
277+
name="Filled Form"
278+
play={async ({ args, canvas, userEvent }) => {
279+
// Simulate a user filling out the form
280+
await userEvent.type(canvas.getByTestId('email'), '[email protected]');
281+
await userEvent.type(canvas.getByTestId('password'), 'a-random-password');
282+
await userEvent.click(canvas.getByRole('button'));
283+
284+
// Run assertions
285+
await expect(args.onSubmit).toHaveBeenCalledTimes(1);
286+
await expect(canvas.getByText('You’re in!')).toBeInTheDocument();
287+
}}
288+
/>
289+
```
290+
249291
## E2E tests using Playwright
250292

251293
E2E (short for 'end to end') tests allow you to test your full application through the eyes of the user. This section uses [Playwright](https://playwright.dev/) as an example, but you can also use other solutions like [Cypress](https://www.cypress.io/) or [NightwatchJS](https://nightwatchjs.org/).

0 commit comments

Comments
 (0)