
让 AI 理解你的业务逻辑,自动生成高质量单元测试
在软件工程的演进中,测试始终是保障质量的基石。但写测试用例——尤其是覆盖边界条件和复杂业务规则的用例——往往枯燥、耗时,且容易遗漏关键路径。
有没有可能,让 AI 帮你读懂代码中的业务规则,并自动生成精准的测试用例?
答案是:可以! 而关键在于:如何将“隐式”的业务逻辑,转化为 AI 能理解的“显式”结构化规则。
本文将带你从零构建一个 **AI 测试 Harness(测试夹具)**,实现 “规则提取 → LLM 理解 → 测试生成” 的完整闭环。
你可能试过让 LLM(如 GPT、Claude、Ollama)为函数写单元测试:
go编辑
func NeedCaptcha(phone string) bool {
if phone == "" { return true }
member, _ := repo.GetByPhone(phone)
if member != nil && member.IsVIP { return false }
return true
}
但 AI 给出的测试往往是:
phone == "" 和普通手机号IsVIP 是关键判断条件原因很简单:AI 看不懂“注释”和“意图”,它只能看到代码表面。
而业务规则,往往藏在:
if 条件组合中我们要做的,是把函数中的 控制流逻辑 转化为 结构化的规则列表,例如:
json编辑
{
"name": "NeedCaptcha",
"rules": [
{
"condition": "phone == \"\"",
"action": "true",
"calls": []
},
{
"condition": "err != nil",
"action": "true",
"calls": ["repo.GetByPhone(...)"]
},
{
"condition": "member != null && member.IsVIP",
"action": "false",
"calls": ["repo.GetByPhone(...)"]
},
{
"condition": "default (unconditional)",
"action": "true",
"calls": ["repo.GetByPhone(...)"]
}
]
}
这个 JSON 就是 AI 的“说明书” ——它清晰地告诉 LLM:
“当手机号为空时,返回 true;当数据库查询失败时,也返回 true;只有 VIP 用户才返回 false……”
我们使用 Go 的标准库 go/ast 编写一个轻量级提取器:https://github.com/shemiouwang-lgtm/go-ast-rule-extractor
bash编辑
# 安装后,一行命令提取规则
go run rule-extractor.go --file user_service.go --func NeedCaptcha --json
输出即为上述结构化 JSON。
if / else if / return 分支&&、||、索引、类型断言等)repo.GetByPhone)💡 提示:该工具无第三方依赖,纯标准库实现,可集成到 CI/CD 中。
有了结构化规则,我们就可以构造 LLM Prompt:
text编辑
你是一个资深 Go 测试工程师。请为以下函数生成 100% 分支覆盖的单元测试。
函数名:NeedCaptcha
业务规则:
[
{"condition": "phone == \"\"", "action": "true"},
{"condition": "err != nil", "action": "true"},
{"condition": "member != null && member.IsVIP", "action": "false"},
{"condition": "default", "action": "true"}
]
要求:
1. 使用 testify/mock
2. 每个规则对应一个 test case
3. 测试用例命名清晰(如 TestNeedCaptcha_EmptyPhone_ReturnsTrue)
4. 覆盖所有边界条件
go编辑
func TestNeedCaptcha_EmptyPhone_ReturnsTrue(t *testing.T) {
s := &UserService{}
assert.True(t, s.NeedCaptcha(""))
}
func TestNeedCaptcha_RepoError_ReturnsTrue(t *testing.T) {
mockRepo := new(MockMemberRepo)
mockRepo.On("GetByPhone", "13800138000").Return(nil, errors.New("db error"))
s := &UserService{memberRepo: mockRepo}
assert.True(t, s.NeedCaptcha("13800138000"))
}
func TestNeedCaptcha_VIPUser_ReturnsFalse(t *testing.T) {
mockRepo := new(MockMemberRepo)
mockRepo.On("GetByPhone", "13800138000").Return(&Member{IsVIP: true}, nil)
s := &UserService{memberRepo: mockRepo}
assert.False(t, s.NeedCaptcha("13800138000"))
}
✅ 精准覆盖所有规则 ✅ 命名规范,可读性强 ✅ 自动 mock 依赖
将上述流程封装为一个 AI 测试 Harness:
文本编辑
[源代码]
↓ (AST 规则提取)
[结构化规则 JSON]
↓ (LLM Prompt)
[AI 生成的测试代码]
↓ (静态检查 + 执行)
[测试报告 + 覆盖率]
表格
传统方式 | AI 测试 Harness |
|---|---|
开发者凭经验写测试 | AI 基于完整规则生成 |
容易遗漏边界条件 | 100% 分支覆盖 |
测试与代码脱节 | 测试与最新规则同步 |
新人难上手 | 规则即文档,AI 即导师 |
更重要的是:你把“业务规则”从代码中显式提炼出来,形成了可追溯、可验证的知识资产。