文档
Storybook 文档

端到端测试中的故事

Storybook 与其他测试框架(例如 CypressPlaywright)无缝集成,提供全面的测试解决方案。通过利用组件故事格式 (CSF),开发人员可以编写测试用例,模拟用户交互并验证 Storybook 环境中单个组件的行为。这种方法使开发人员能够全面测试其组件的功能、响应能力和视觉外观,从而实现更强大、更可靠的应用程序。

使用 Cypress

Cypress 是一种端到端测试框架。它允许您通过模拟用户行为来测试应用程序的完整实例。使用组件故事格式,您的故事可以在 Cypress 中重复使用。每个命名导出(换句话说,一个故事)都可以在您的测试设置中渲染。

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

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.org.cn/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 protected]');
 
    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();
  },
};

播放函数包含在故事渲染后运行的少量代码片段。它允许您在故事中排序交互。

使用 Cypress,您可以编写以下测试

/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 protected]');
      cy.log('**enter password**');
      cy.get('#password').should('have.value', 'a-random-password');
    });
  });
});

当 Cypress 运行您的测试时,它会加载 Storybook 的隔离 iframe 并检查输入是否与测试值匹配。

Cypress running successfully

使用 Playwright

Playwright 是来自 Microsoft 的一个浏览器自动化工具和端到端测试框架。它提供了跨浏览器自动化、使用设备模拟进行移动测试以及无头测试。使用组件故事格式,您的故事可以在 Playwright 中重复使用。每个命名导出(换句话说,一个故事)都可以在您的测试设置中渲染。

使用 Playwright 进行用户流程测试的一个实际场景是测试登录表单的有效性。例如,如果您已经创建了以下故事

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.org.cn/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 protected]');
 
    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();
  },
};

播放函数包含在故事渲染后运行的少量代码片段。它允许您在故事中排序交互。

您可以使用 Playwright 编写测试以检查输入是否已填写并与故事匹配

tests/login-form/login.spec.js
const { test, expect } = require('@playwright/test');
 
test('Login Form inputs', async ({ page }) => {
  await page.goto('https://127.0.0.1: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 protected]');
  await expect(password).toBe('a-random-password');
});

执行 Playwright 后,它会打开一个新的浏览器窗口,加载 Storybook 的隔离 iframe,断言输入是否包含指定的值,并在终端中显示测试结果。

了解其他 UI 测试