202 lines
3.5 KiB
Markdown
202 lines
3.5 KiB
Markdown
# 测试
|
|
|
|
## Vitest 配置
|
|
|
|
```bash
|
|
pnpm add -D vitest
|
|
```
|
|
|
|
### 基础配置
|
|
|
|
```typescript
|
|
// vitest.config.ts
|
|
import { defineConfig } from 'vitest/config'
|
|
|
|
export default defineConfig({
|
|
test: {
|
|
include: ['test/**/*.test.ts'],
|
|
testTimeout: 30_000,
|
|
reporters: 'dot',
|
|
},
|
|
})
|
|
```
|
|
|
|
### 含覆盖率
|
|
|
|
```typescript
|
|
export default defineConfig({
|
|
test: {
|
|
coverage: {
|
|
provider: 'v8',
|
|
include: ['src/**/*.ts'],
|
|
exclude: ['src/types.ts'],
|
|
reporter: ['text', 'lcovonly', 'html'],
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
## 工作空间项目
|
|
|
|
对于 monorepo,可以分别测试各个包:
|
|
|
|
```typescript
|
|
export default defineConfig({
|
|
test: {
|
|
projects: [
|
|
'packages/*/vitest.config.ts',
|
|
{
|
|
extends: './vitest.config.ts',
|
|
test: { name: 'unit', environment: 'node' },
|
|
},
|
|
{
|
|
extends: './vitest.config.ts',
|
|
test: { name: 'browser', browser: { enabled: true } },
|
|
},
|
|
],
|
|
},
|
|
})
|
|
```
|
|
|
|
## 基于 Fixture 的测试
|
|
|
|
使用文件 fixture 测试转换:
|
|
|
|
```typescript
|
|
import { describe, expect, it } from 'vitest'
|
|
import { transform } from '../src'
|
|
|
|
const fixtures = import.meta.glob('./fixtures/*.ts', { as: 'raw' })
|
|
|
|
describe('transform', () => {
|
|
for (const [path, getContent] of Object.entries(fixtures)) {
|
|
it(path, async () => {
|
|
const content = await getContent()
|
|
const result = await transform(content)
|
|
expect(result).toMatchSnapshot()
|
|
})
|
|
}
|
|
})
|
|
```
|
|
|
|
## 幂等性测试
|
|
|
|
确保转换是稳定的:
|
|
|
|
```typescript
|
|
it('transform is idempotent', async () => {
|
|
const pass1 = (await transform(fixture))?.code ?? fixture
|
|
expect(pass1).toMatchSnapshot()
|
|
|
|
const pass2 = (await transform(pass1))?.code ?? pass1
|
|
expect(pass2).toBe(pass1) // 不应发生变化
|
|
})
|
|
```
|
|
|
|
## 类型级测试
|
|
|
|
测试 TypeScript 类型:
|
|
|
|
```typescript
|
|
// vitest.config.ts
|
|
export default defineConfig({
|
|
test: {
|
|
typecheck: { enabled: true },
|
|
},
|
|
})
|
|
```
|
|
|
|
```typescript
|
|
// test/types.test-d.ts
|
|
import { describe, expectTypeOf, it } from 'vitest'
|
|
import type { Input, Output } from '../src'
|
|
|
|
describe('types', () => {
|
|
it('infers input correctly', () => {
|
|
expectTypeOf<Input<typeof schema>>().toEqualTypeOf<{ id: string }>()
|
|
})
|
|
})
|
|
```
|
|
|
|
## 多 TS 版本测试
|
|
|
|
跨 TypeScript 版本测试(TanStack 模式):
|
|
|
|
```yaml
|
|
# .github/workflows/ci.yml
|
|
jobs:
|
|
test-types:
|
|
strategy:
|
|
matrix:
|
|
ts: ['5.0', '5.2', '5.4', '5.6', '5.8']
|
|
steps:
|
|
- run: pnpm add -D typescript@${{ matrix.ts }}
|
|
- run: pnpm typecheck
|
|
```
|
|
|
|
## 包验证
|
|
|
|
验证发布后的包:
|
|
|
|
```bash
|
|
# 检查导出是否正确
|
|
pnpm dlx publint
|
|
|
|
# 检查类型在不同 moduleResolution 下是否正常工作
|
|
pnpm dlx @arethetypeswrong/cli --pack .
|
|
```
|
|
|
|
添加到 tsdown 配置:
|
|
|
|
```typescript
|
|
export default defineConfig({
|
|
attw: { profile: 'esm-only' }, // 或 'node16'
|
|
})
|
|
```
|
|
|
|
## 测试脚本
|
|
|
|
```json
|
|
{
|
|
"scripts": {
|
|
"test": "vitest",
|
|
"test:run": "vitest run",
|
|
"test:coverage": "vitest run --coverage",
|
|
"test:types": "vitest typecheck"
|
|
}
|
|
}
|
|
```
|
|
|
|
## Mock
|
|
|
|
```typescript
|
|
import { vi } from 'vitest'
|
|
|
|
vi.mock('fs', () => ({
|
|
readFileSync: vi.fn(() => 'mocked content'),
|
|
}))
|
|
|
|
// 监听方法
|
|
const spy = vi.spyOn(console, 'log')
|
|
expect(spy).toHaveBeenCalledWith('expected')
|
|
```
|
|
|
|
## 测试插件
|
|
|
|
在测试中自己使用自己的插件:
|
|
|
|
```typescript
|
|
// vitest.config.ts
|
|
import { defineConfig } from 'vitest/config'
|
|
import MyPlugin from './src/vite'
|
|
|
|
export default defineConfig({
|
|
plugins: [
|
|
MyPlugin({ /* 选项 */ }),
|
|
],
|
|
test: {
|
|
include: ['test/**/*.test.ts'],
|
|
},
|
|
})
|
|
```
|