端到端测试中的 Story
Storybook 与 Cypress 和 Playwright 等其他测试框架无缝集成,提供全面的测试解决方案。通过利用组件 Story 格式 (CSF),开发人员可以编写测试用例,模拟用户交互,并在 Storybook 环境中验证单个组件的行为。这种方法使开发人员能够彻底测试其组件在不同场景下的功能、响应性和视觉外观,从而构建更健壮、更可靠的应用程序。
配合 Cypress
Cypress 是一个端到端测试框架。它允许您通过模拟用户行为来测试应用程序的完整实例。使用组件 Story 格式,您的 Story 可以与 Cypress 重复使用。每个命名的导出(换句话说,一个 Story)都可以在您的测试设置中渲染。
使用 Cypress 和 Storybook 进行端到端测试的一个例子是测试登录组件的正确输入。例如,如果您有以下 Story:
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { expect } from 'storybook/test';
import { LoginForm } from './LoginForm';
const meta = {
component: LoginForm,
} satisfies Meta<typeof LoginForm>;
export default meta;
type Story = StoryObj<typeof meta>;
export const EmptyForm: Story = {};
export const FilledForm: Story = {
play: async ({ canvas, userEvent }) => {
// 👇 Simulate interactions with the component
await userEvent.type(canvas.getByTestId('email'), 'email@provider.com');
await userEvent.type(canvas.getByTestId('password'), 'a-random-password');
// See https://storybook.org.cn/docs/essentials/actions#automatically-matching-args to learn how to setup logging in the Actions panel
await userEvent.click(canvas.getByRole('button'));
// 👇 Assert DOM structure
await expect(
canvas.getByText(
'Everything is perfect. Your account is ready and we should probably get you started!',
),
).toBeInTheDocument();
},
};play 函数包含在 Story 渲染后运行的小代码片段。它允许您在 Story 中进行交互排序。
使用 Cypress,您可以编写以下测试:
/// <reference types="cypress" />
describe('Login Form', () => {
it('Should contain valid login information', () => {
cy.visit('/iframe.html?id=components-login-form--example');
cy.get('#login-form').within(() => {
cy.log('**enter the email**');
cy.get('#email').should('have.value', 'email@provider.com');
cy.log('**enter password**');
cy.get('#password').should('have.value', 'a-random-password');
});
});
});当 Cypress 运行您的测试时,它会加载 Storybook 的独立 iframe,并检查输入是否与测试值匹配。
配合 Playwright
Playwright 是 Microsoft 开发的浏览器自动化工具和端到端测试框架。它提供跨浏览器自动化、设备模拟的移动测试以及无头测试。使用组件 Story 格式,您的 Story 可以与 Playwright 重复使用。每个命名的导出(换句话说,一个 Story)都可以在您的测试设置中渲染。
使用 Playwright 进行用户流程测试的一个实际场景是如何测试登录表单的有效性。例如,如果您已经创建了以下 Story:
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { expect } from 'storybook/test';
import { LoginForm } from './LoginForm';
const meta = {
component: LoginForm,
} satisfies Meta<typeof LoginForm>;
export default meta;
type Story = StoryObj<typeof meta>;
export const EmptyForm: Story = {};
export const FilledForm: Story = {
play: async ({ canvas, userEvent }) => {
// 👇 Simulate interactions with the component
await userEvent.type(canvas.getByTestId('email'), 'email@provider.com');
await userEvent.type(canvas.getByTestId('password'), 'a-random-password');
// See https://storybook.org.cn/docs/essentials/actions#automatically-matching-args to learn how to setup logging in the Actions panel
await userEvent.click(canvas.getByRole('button'));
// 👇 Assert DOM structure
await expect(
canvas.getByText(
'Everything is perfect. Your account is ready and we should probably get you started!',
),
).toBeInTheDocument();
},
};play 函数包含在 Story 渲染后运行的小代码片段。它允许您在 Story 中进行交互排序。
使用 Playwright,您可以编写一个测试来检查输入是否已填写并与 Story 匹配
import { test, expect } from '@playwright/test';
test('Login Form inputs', async ({ page }) => {
await page.goto('https://:6006/iframe.html?id=components-login-form--example');
const email = await page.inputValue('#email');
const password = await page.inputValue('#password');
await expect(email).toBe('email@provider.com');
await expect(password).toBe('a-random-password');
});一旦您执行 Playwright,它会打开一个新的浏览器窗口,加载 Storybook 的独立 iframe,断言输入是否包含指定的值,并在终端中显示测试结果。
更多测试资源
