89 lines
No EOL
2.9 KiB
Markdown
89 lines
No EOL
2.9 KiB
Markdown
# 开发
|
|
|
|
## 本地开发
|
|
|
|
开发电子邮件编辑最高效的方法是使用 WooCommerce 插件的 watch 命令:
|
|
|
|
```bash
|
|
pnpm --filter='@woocommerce/plugin-woocommerce' watch:build:admin
|
|
```
|
|
|
|
## 运行测试
|
|
|
|
### JavaScript 组件测试
|
|
|
|
要运行 JS 包中的组件测试:
|
|
|
|
```bash
|
|
pnpm run test:js
|
|
```
|
|
|
|
要运行特定的测试文件:
|
|
|
|
```bash
|
|
pnpm run test:js -- src/components/my-component/test/my-component.spec.tsx
|
|
```
|
|
|
|
我们使用 [Jest](https://jestjs.io/) 配合 `@testing-library/react`。这些是**组件测试**,不是严格的单元测试,并且包含模拟的依赖项。
|
|
|
|
#### 组件测试撰写指南
|
|
|
|
- 在测试名称中使用 `should` 前缀(例如:`should render the modal`)。
|
|
- 避免测试实现细节。优先使用可见的 DOM 断言。
|
|
- 使用 [jest.fn()](https://jestjs.io/docs/mock-functions) 和 [jest.mock()](https://jestjs.io/docs/manual-mocks) 进行模拟。
|
|
- 在导入被测试组件**前**,始终模拟所需的依赖项。
|
|
- 避免为仅是第三方库简单包装的组件编写测试(例如,仅渲染 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`。
|
|
|
|
可重用模拟设置的例子:
|
|
|
|
```ts
|
|
// __mocks__/setup-shared-mocks.ts
|
|
jest.mock('@wordpress/data', () => ({
|
|
useSelect: jest.fn(),
|
|
useDispatch: jest.fn(),
|
|
createRegistrySelector: jest.fn(),
|
|
}));
|
|
```
|
|
|
|
#### 基础组件测试示例
|
|
|
|
```tsx
|
|
/* 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](packages/packages/js/email-editor/writing-e2e-tests) |