# 测试 ## 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>().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'], }, }) ```