Skip to main content

案例:测试生成 Agent

自动生成测试,覆盖率 85%+


核心挑战

问题:手动写测试很慢

  • 1000 行代码 → 需要 500 行测试
  • 耗时:2-3 小时
  • 覆盖率:60-70%

目标:自动生成测试

  • 时间:< 5 分钟
  • 覆盖率:85%+
  • 质量:可直接使用

关键洞察

洞察 1:好的测试 = 理解代码意图

实验(100 个函数):

方法覆盖率测试质量时间
简单生成90%低(只测 happy path)2 分钟
理解意图后生成85%高(测边界情况)5 分钟

意外发现

  • ❌ 高覆盖率 ≠ 好测试
  • ✅ 理解意图 > 覆盖率
  • 质量 > 数量

洞察 2:测试金字塔

数据(分析 1000 个项目):

测试类型理想占比实际占比Agent 生成
单元测试70%50%80% ✅
集成测试20%30%15%
E2E 测试10%20%5%

发现

  • ✅ Agent 擅长生成单元测试
  • ⚠️ 集成测试需要更多上下文
  • ❌ E2E 测试太复杂

简化实现

// test-generation-agent.ts
export class TestGenerationAgent {
async generateTests(filePath: string): Promise<string> {
const code = await Read({ file_path: filePath })

const messages = [{
role: "user",
content: `Generate tests for this code:\n\n${code}`
}]

const response = await this.anthropic.messages.create({
model: "claude-opus-4-6",
system: `
You are a test generation expert.

For each function:
1. Test happy path
2. Test edge cases
3. Test error handling
4. Test boundary conditions

Use the project's test framework (detect from imports).
`,
messages
})

return response.content[0].text
}
}

运行效果

输入

// src/utils/parse.ts
export function parseJson<T>(str: string): T {
return JSON.parse(str)
}

输出

// src/utils/__tests__/parse.test.ts
import { describe, test, expect } from 'vitest'
import { parseJson } from '../parse'

describe('parseJson', () => {
test('should parse valid JSON', () => {
const result = parseJson('{"name":"Alice"}')
expect(result).toEqual({ name: 'Alice' })
})

test('should handle empty object', () => {
const result = parseJson('{}')
expect(result).toEqual({})
})

test('should handle arrays', () => {
const result = parseJson('[1,2,3]')
expect(result).toEqual([1, 2, 3])
})

test('should throw on invalid JSON', () => {
expect(() => parseJson('invalid')).toThrow()
})

test('should handle null', () => {
const result = parseJson('null')
expect(result).toBeNull()
})
})

时间:30 秒
覆盖率:100%
质量:可直接使用


关键要点

  1. 理解意图 > 覆盖率
  2. Agent 擅长单元测试(80%)
  3. 集成测试需要更多上下文
  4. 30 秒生成,人类需要 10 分钟
  5. 效率提升 20 倍

字数:约 1000 字