ice/website/docs/guide/advanced/unit-test.md

270 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 单元测试
order: 0401
---
<details open>
<summary>示例</summary>
<ul>
<li>
<a href="https://github.com/alibaba/ice/tree/master/examples/with-jest" target="_blank" rel="noopener noreferrer">
with-jest
</a>
</li>
<li>
<a href="https://github.com/alibaba/ice/tree/master/examples/with-vitest" target="_blank" rel="noopener noreferrer">
with-vitest
</a>
</li>
</ul>
</details>
ice.js 不耦合任何一个测试框架,开发者可自由选择。目前提供开箱即用的 [jest](https://jestjs.io/) 和 [vitest](https://vitest.dev/) 配置,以便快速开始单元测试。
## Jest
### 依赖安装
```bash
$ npm i jest -D
```
> 如果使用 TypeScript 编写单元测试,推荐接入使用 [@swc/jest](https://swc.rs/docs/usage/jest) 或 [ts-jest](https://kulshekhar.github.io/ts-jest/docs/getting-started/installation)
### 配置
首先需要在项目的根目录下新建 `jest.config.mjs` 文件,并加入以下内容:
```js title="jest.config.mjs"
import { defineJestConfig } from '@ice/app';
export default defineJestConfig({});
```
`defineJestConfig` 方法返回的是 ice.js 默认配置好的 Jest 配置,支持传入自定义的 [Jest 配置](https://jestjs.io/docs/configuration)。
`defineJestConfig` 入参支持两种写法:
- `jest.Config`
- `() => Promise<jest.Config>`
以添加 `@swc/jest` 为例:
```diff title="jest.config.mjs"
import { defineJestConfig } from '@ice/app';
export default defineJestConfig({
+ transform: {
+ '^.+\\.(t|j)sx?$': [
+ '@swc/jest',
+ {
+ // swc 配置
+ jsc: {
+ transform: {
+ react: {
+ runtime: 'automatic',
+ },
+ },
+ },
+ },
+ ],
+ },
});
```
然后在 `package.json` 中加入 `test` 脚本:
```diff title="package.json"
{
"scripts": {
+ "test": "jest"
}
}
```
配置完成后,就可以开始编写单元测试了。
### 非 UI 测试
假设现在要测试 `add` 函数如下:
```ts title="src/utils/add.ts"
export default function add(a, b) {
return a + b;
}
```
新建一个测试用例:
```ts title="tests/add.spec.ts"
import add from '../src/add';
test('add function', () => {
expect(add(1, 2)).toBe(3);
});
```
这时,运行 `npm run test` 查看测试结果了。
### UI 测试
组件 UI 测试推荐使用 [@testing-library/react](https://www.npmjs.com/package/@testing-library/react) 和 [@testing-library/jest-dom](https://www.npmjs.com/package/@testing-library/jest-dom)。
首先安装依赖:
```bash
$ npm i @testing-library/react jest-environment-jsdom @testing-library/jest-dom -D
```
然后在项目根目录下新建 `jest-setup.ts` 并写入以下内容,以扩展匹配器(matchers)
```ts title="jest-setup.ts"
import '@testing-library/jest-dom';
```
最后在 `jest.config.mjs` 中加入以下内容:
```diff title="jest.config.mjs"
import { defineJestConfig } from '@ice/app';
export default defineJestConfig({
+ setupFilesAfterEnv: ['<rootDir>/jest-setup.ts'],
+ testEnvironment: 'jest-environment-jsdom',
});
```
假设现在要测试一个 Header 组件:
```tsx title="src/components/Header.tsx"
export default function Header() {
return (
<h2 data-testid="title">Jest Test</h2>
);
}
```
编写组件的测试用例:
```tsx title="tests/Header.spec.tsx"
import { render, screen } from '@testing-library/react';
import Header from '@/components/Header';
test('test Header component', () => {
render(<Header />);
expect(screen.getByTestId('title')).toHaveTextContent('Jest Test');
});
```
最后,运行 `npm run test` 就可以查看测试结果了。
## Vitest
### 依赖安装
```bash
$ npm i vitest -D
```
### 配置
首先需要在项目的根目录下新建 vitest.config.mjs 文件,并加入以下内容:
```js title="vitest.config.mjs"
import { defineVitestConfig } from '@ice/app';
export default defineVitestConfig({});
```
`defineVitestConfig` 方法返回的是 ice.js 默认配置好的 vitest 配置,支持传入自定义的 [vitest 配置](https://vitest.dev/config/)。
defineVitestConfig 入参支持三种写法:
- `vitest.UserConfig`
- `Promise<vitest.UserConfig>`
- `(env) => Promise<vitest.UserConfig>`
以修改 `include` 参数为例:
```diff title="vitest.config.mjs"
import { defineVitestConfig } from '@ice/app';
export default defineVitestConfig({
+ test: {
+ include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']
+ }
});
```
然后在 `package.json` 中加入 `test` 脚本:
```diff title="package.json"
{
"scripts": {
+ "test": "vitest"
}
}
```
### 非 UI 测试
同样测试 [Jest 非 UI 测试章节](#非-ui-测试) 中的 `Header` 组件,编写以下的测试用例:
```ts title="tests/add.spec.ts"
import { test, expect } from 'vitest';
import add from '../src/add';
test('add', () => {
expect(add(1, 2)).toBe(3);
});
```
现在可以运行 `npm run test` 查看测试结果。
### UI 测试
首先安装依赖:
```bash
$ npm i @testing-library/react jsdom @testing-library/jest-dom @vitejs/plugin-react@1.3.2 -D
```
然后在项目根目录下新建 `vitest-setup.js` 并写入以下内容,以扩展匹配器(matchers)
```ts title="vitest-setup.js"
import matchers from '@testing-library/jest-dom/matchers';
import { expect } from 'vitest';
expect.extend(matchers);
```
最后在 `vitest.config.mjs` 中加入以下内容:
```diff title="vitest.config.mjs"
import { defineVitestConfig } from '@ice/app';
+ import react from '@vitejs/plugin-react';
export default defineVitestConfig({
+ test: {
+ environment: 'jsdom',
+ setupFiles: ['./vitest-setup.js'],
+ plugins: [react()], // 支持解析 JSX 语法
+ },
});
```
假设现在测试一个 Header 组件:
```tsx title="src/components/Header.tsx"
export default function Header() {
return (
<h2 data-testid="title">Vitest Test</h2>
);
}
```
编写组件的测试用例:
```tsx title="tests/Header.spec.tsx"
import { test, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import Header from '@/components/Header';
test('test Header component', () => {
render(<Header />);
expect(screen.getByTestId('title')).toHaveTextContent('Vitest Test');
});
```
最后,运行 `npm run test` 就可以查看测试结果了。