Docs
Storybook Docs

端到端测试中的故事

Storybook 与 CypressPlaywright 等其他测试框架无缝集成,提供全面的测试解决方案。通过利用组件故事格式 (CSF),开发者可以编写测试用例来模拟用户交互并验证 Storybook 环境中各个组件的行为。这种方法使开发者能够在不同场景中彻底测试其组件的功能、响应能力和视觉外观,从而产生更强大、更可靠的应用。

¥Storybook seamlessly integrates with additional testing frameworks like Cypress and Playwright to provide a comprehensive testing solution. By leveraging the Component Story Format (CSF), developers can write test cases that simulate user interactions and verify the behavior of individual components within the Storybook environment. This approach enables developers to thoroughly test their components' functionality, responsiveness, and visual appearance across different scenarios, resulting in more robust and reliable applications.

使用 Cypress

¥With Cypress

Cypress 是一个端到端测试框架。它使你能够通过模拟用户行为来测试应用的完整实例。使用 Component Story Format,你的故事可以与 Cypress 一起重复使用。每个命名导出(换句话说,一个故事)都可以在你的测试设置中渲染。

¥Cypress is an end-to-end testing framework. It enables you to test a complete instance of your application by simulating user behavior. With Component Story Format, your stories are reusable with Cypress. Each named export (in other words, a story) is renderable within your testing setup.

使用 Cypress 和 Storybook 进行端到端测试的一个示例是测试登录组件的正确输入。例如,如果你有以下故事:

¥An example of an end-to-end test with Cypress and Storybook is testing a login component for the correct inputs. For example, if you had the following story:

LoginForm.stories.ts|tsx
import type { Meta, StoryObj } from '@storybook/react';
 
import { userEvent, within, expect } from '@storybook/test';
 
import { LoginForm } from './LoginForm';
 
const meta: Meta<typeof LoginForm> = {
  component: LoginForm,
};
 
export default meta;
type Story = StoryObj<typeof LoginForm>;
 
export const EmptyForm: Story = {};
 
/*
 * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas
 * to learn more about using the canvasElement to query the DOM
 */
export const FilledForm: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
 
    // 👇 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.js.org/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 函数包含在故事渲染后运行的小代码片段。它允许你对故事中的交互进行排序。

¥The play function contains small snippets of code that run after the story renders. It allows you to sequence interactions in stories.

使用 Cypress,你可以编写以下测试:

¥With Cypress, you could write the following test:

/cypress/integration/Login.spec.js
/// <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 并检查输入是否与测试值匹配。

¥When Cypress runs your test, it loads Storybook's isolated iframe and checks if the inputs match the test values.

Cypress running successfully

使用 Playwright

¥With Playwright

Playwright 是来自 Microsoft 的浏览器自动化工具和端到端测试框架。它提供跨浏览器自动化、带有设备模拟的移动测试和无头测试。使用 Component Story Format,你的故事可以与 Playwright 一起重复使用。每个命名导出(换句话说,一个故事)都可以在你的测试设置中渲染。

¥Playwright is a browser automation tool and end-to-end testing framework from Microsoft. It offers cross-browser automation, mobile testing with device emulation, and headless testing. With Component Story Format, your stories are reusable with Playwright. Each named export (in other words, a story) is renderable within your testing setup.

使用 Playwright 进行用户流测试的真实场景是如何测试登录表单的有效性。例如,如果你已经创建了以下故事:

¥A real-life scenario of user flow testing with Playwright would be how to test a login form for validity. For example, if you had the following story already created:

LoginForm.stories.ts|tsx
import type { Meta, StoryObj } from '@storybook/react';
 
import { userEvent, within, expect } from '@storybook/test';
 
import { LoginForm } from './LoginForm';
 
const meta: Meta<typeof LoginForm> = {
  component: LoginForm,
};
 
export default meta;
type Story = StoryObj<typeof LoginForm>;
 
export const EmptyForm: Story = {};
 
/*
 * See https://storybook.js.org/docs/writing-stories/play-function#working-with-the-canvas
 * to learn more about using the canvasElement to query the DOM
 */
export const FilledForm: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
 
    // 👇 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.js.org/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 函数包含在故事渲染后运行的小代码片段。它允许你对故事中的交互进行排序。

¥The play function contains small snippets of code that run after the story renders. It allows you to sequence interactions in stories.

使用 Playwright,你可以编写测试来检查输入是否已填写并与故事相匹配:

¥With Playwright, you can write a test to check if the inputs are filled and match the story:

tests/login-form/login.spec.js
const { test, expect } = require('@playwright/test');
 
test('Login Form inputs', async ({ page }) => {
  await page.goto('http://localhost: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,断言输入是否包含指定的值,并在终端中显示测试结果。

¥Once you execute Playwright, it opens a new browser window, loads Storybook's isolated iframe, asserts if the inputs contain the specified values, and displays the test results in the terminal.

了解其他 UI 测试

¥Learn about other UI tests