让 AI 参与测试:能做什么、不能做什么

AI 在测试上最强的地方,是把一条已经说清楚的判断批量展开成用例;最弱的地方,是替你做出判断。这两件事分清了,AI 参与测试的收益立刻为正;分不清,就会拿到一堆永远绿灯、也永远抓不到缺陷(bug)的测试文件。

1. 能力边界对照表

任务AI 表现原因必须由人做的事
按签名补表驱动用例强模板高度确定补上业务特有场景
生成通用边界值(0/负/空/超大/Unicode)强属于通用工程常识判断哪些边界在本业务里合法
写桩(stub)与假实现(fake)骨架强接口即契约,生成成本低判断替身行为与真依赖是否一致
断言「业务上应该是什么」弱模型没有你的领域上下文全部
判定金额、时区、权限的期望值弱领域规则不在训练数据里全部
决定覆盖率与性能的验收阈值弱阈值是团队决策,不是知识全部
读报错猜原因并给最小复现中会编造不存在的栈帧与字段提供真实日志并核对结论

一句话:AI 产出的是「候选用例」,不是「正确答案」。

2. 把验收标准当输入,而不是当结果

提示词里必须写清「输入 → 期望输出」的契约,契约来自需求条目、接口文档或校验规则;绝不能先跑一遍实现、再让 AI 照抄输出当期望值。后者会把现存缺陷一起固化进测试。

角色:Go 测试工程师。
输入:下面的函数签名与规格说明。
要求:
1. 只用表驱动 + t.Run 子测试,不引入第三方断言库;
2. 每个用例写明 name、输入、期望值、期望错误(用 errors.Is 判断);
3. 覆盖正常值、边界值(0、负数、上限、上限+1)、错误路径、Unicode;
4. 不要修改被测函数,不要运行代码后把输出当期望值;
5. 规格没定义的行为,单独输出「需人工确认」清单,不要自行编造。

函数签名:
func Discount(amount int64, level string) (int64, error)

规格:
- amount 单位为「分」,必须 >= 0,否则返回 ErrInvalidAmount;
- level 只接受 "vip" 与 "normal",其它值返回 ErrUnknownLevel;
- 折扣率:vip 九折、normal 不打折,结果向下取整到分;
- amount 上限 1000000000000 分。

第 5 条是关键:要求它列出「需人工确认」,而不是自己决定,这一句能挡掉大部分幻觉断言。

3. 验收 AI 产出的第一步:弄红实验

拿到测试后先别评审写法,做一次「弄红实验」——故意改坏实现的一行,跑测试看它是否变红。

func TestDiscount(t *testing.T) {
	cases := []struct {
		name      string
		amount    int64
		level     string
		want      int64
		wantErrIs error
	}{
		{"vip 九折", 10000, "vip", 9000, nil},
		{"normal 不打折", 10000, "normal", 10000, nil},
		{"零元不打折", 0, "vip", 0, nil},
		{"负数金额", -1, "vip", 0, ErrInvalidAmount},
		{"未知等级", 100, "gold", 0, ErrUnknownLevel},
		{"上限金额", 1000000000000, "vip", 900000000000, nil},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			got, err := Discount(tc.amount, tc.level)
			if !errors.Is(err, tc.wantErrIs) {
				t.Fatalf("Discount(%d,%q) err = %v, want %v", tc.amount, tc.level, err, tc.wantErrIs)
			}
			if err == nil && got != tc.want {
				t.Errorf("Discount(%d,%q) = %d, want %d", tc.amount, tc.level, got, tc.want)
			}
		})
	}
}

把 vip 的 0.9 改成 0.95,测试必须红。如果全绿,说明断言是照着实现抄的——测试只是实现的复印件,还会拖慢每次重构。

4. 三件绝不交给 AI 的事

  1. 业务语义的正确性:退款金额怎么算、跨时区的时间归属哪一天、权限矩阵里谁能看谁的数据,只有需求方与你能定。
  2. 期望值的来源:期望值来自规格而不是「程序现在的输出」。用输出当期望,等于把现有缺陷固化成「正确行为」。
  3. 验收阈值:覆盖率下限、压测 P99 目标、允许的错误率,这些是决策,不是可检索的知识。

5. 常见坑

  • 套话式断言:只断言 err == nil、只断言响应体非空。AI 很爱写这种「结构性测试」,它什么都证明不了。
  • 隐含假设:默认输入是 ASCII、时间不含夏令时、金额可以用 float。你的业务未必如此。
  • 不可重复:产物里带 time.Now()、rand.Int()、time.Sleep,第二次跑就变红。要求它显式注入时钟与随机源。
  • 编造的接口:模型可能调用不存在的字段、伪造不存在的错误变量。验收先跑 go build ./... 与 go vet ./...。
  • 测试实现细节:断言私有字段、把调用次数写死到具体实现路径,重构一次全红。测试应盯契约,不盯写法。

小结:AI 在测试上是一个高产的「用例候选生成器」,产出质量取决于你喂进去的验收标准有多清楚;用它批量生成、用人工修订期望值、用「弄红实验」验收,把业务语义与阈值始终留在人手里——这就是整套「用 AI 驱动测试」的起点。

笔记加载中…