woocommerce/packages/js/email-editor/zh-cn/development.md
2026-04-15 10:18:01 +08:00

2.9 KiB

开发

本地开发

开发电子邮件编辑最高效的方法是使用 WooCommerce 插件的 watch 命令:

pnpm --filter='@woocommerce/plugin-woocommerce' watch:build:admin

运行测试

JavaScript 组件测试

要运行 JS 包中的组件测试:

pnpm run test:js

要运行特定的测试文件:

pnpm run test:js -- src/components/my-component/test/my-component.spec.tsx

我们使用 Jest 配合 @testing-library/react。这些是组件测试,不是严格的单元测试,并且包含模拟的依赖项。

组件测试撰写指南

  • 在测试名称中使用 should 前缀(例如:should render the modal)。
  • 避免测试实现细节。优先使用可见的 DOM 断言。
  • 使用 jest.fn()jest.mock() 进行模拟。
  • 在导入被测试组件,始终模拟所需的依赖项。
  • 避免为仅是第三方库简单包装的组件编写测试(例如,仅渲染 WordPress 组件而未添加逻辑)。
  • 对于常用包(例如 @wordpress/data@wordpress/components),优先使用可复用的模拟。尽可能创建共享的模拟设置文件。
  • 在模拟组件中使用描述性的 data-testid 属性(例如:data-testid="modal")。
  • 在适用的情况下,使用 screen.getByRole()getByText() 或类似的辅助功能查询。

模拟

  • 将所有模拟保持在测试附近,除非在多个测试中重复使用。
  • 使用共享的模拟设置文件(例如 __mocks__/setup-shared-mocks.ts)以保持单个测试文件的整洁。
  • 对于外部依赖(如 WordPress 包或内部模块),使用 jest.mock()
  • 模拟组件属性时,优先使用 React.ComponentProps<'button'> 或特定的属性界面,以避免使用 any

可重用模拟设置的例子:

// __mocks__/setup-shared-mocks.ts
jest.mock('@wordpress/data', () => ({
  useSelect: jest.fn(),
  useDispatch: jest.fn(),
  createRegistrySelector: jest.fn(),
}));

基础组件测试示例

/* eslint-disable @woocommerce/dependency-group -- 由于我们先导入模拟文件,因此停用此规则以避免 ESLint 错误 */
import '../../__mocks__/setup-shared-mocks';

/**
 * 外部依赖
 */
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';

/**
 * 内部依赖
 */
import { MyComponent } from '../my-component';

describe('MyComponent', () => {
  it('应该渲染一个按钮并响应点击', () => {
    const onClickMock = jest.fn();
    render(<MyComponent onClick={onClickMock} />);
    const button = screen.getByRole('button', { name: /click me/i });
    expect(button).toBeInTheDocument();
    fireEvent.click(button);
    expect(onClickMock).toHaveBeenCalled();
  });
});

E2E 测试

E2E 测试:writing-e2e-tests.md