文件
Storybook 文件

端對端測試中的 Stories

Storybook 與其他測試框架(如 CypressPlaywright)無縫整合,以提供全面的測試解決方案。透過利用元件 Story 格式 (CSF),開發人員可以編寫測試案例,模擬使用者互動並驗證 Storybook 環境中各個元件的行為。此方法讓開發人員能夠徹底測試其元件在不同情境下的功能、回應性和視覺外觀,從而產生更穩健且可靠的應用程式。

使用 Cypress

Cypress 是一種端對端測試框架。它讓您能夠透過模擬使用者行為來測試應用程式的完整執行個體。使用元件 Story 格式,您的 stories 可與 Cypress 重複使用。每個具名匯出 (換句話說,就是一個 story) 都可在您的測試設定中呈現。

使用 Cypress 和 Storybook 進行端對端測試的一個範例是測試登入元件是否具有正確的輸入。例如,如果您有以下 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.dev.org.tw/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.dev.org.tw/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 呈現後執行的小程式碼片段。它讓您可以在 stories 中排序互動。

使用 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@provider.com');
      cy.log('**enter password**');
      cy.get('#password').should('have.value', 'a-random-password');
    });
  });
});

當 Cypress 執行您的測試時,它會載入 Storybook 的隔離 iframe,並檢查輸入是否與測試值相符。

Cypress running successfully

使用 Playwright

Playwright 是 Microsoft 的瀏覽器自動化工具和端對端測試框架。它提供跨瀏覽器自動化、裝置模擬的行動測試和無頭測試。使用元件 Story 格式,您的 stories 可與 Playwright 重複使用。每個具名匯出 (換句話說,就是一個 story) 都可在您的測試設定中呈現。

使用 Playwright 進行使用者流程測試的一個真實案例是如何測試登入表單的有效性。例如,如果您已經建立以下 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.dev.org.tw/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.dev.org.tw/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 呈現後執行的小程式碼片段。它讓您可以在 stories 中排序互動。

使用 Playwright,您可以編寫測試來檢查輸入是否已填寫並與 story 相符

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@provider.com');
  await expect(password).toBe('a-random-password');
});

一旦您執行 Playwright,它會開啟新的瀏覽器視窗、載入 Storybook 的隔離 iframe、斷言輸入是否包含指定的值,並在終端機中顯示測試結果。

瞭解其他 UI 測試