浏览 AI使用教程
AI 写的测试为什么会假通过,怎样检查断言有没有用
测试显示绿色,不一定真的验证了行为。检查断言对象、失败分支和故障注入,才能发现只调用不判断、先 mock 成功再证明成功的假测试。
测试名写着“应拒绝”,代码却从来没有检查拒绝结果
200减10%应为180,错误220也能通过toBeTruthy;0却不能,所以该断言不是永远为真,而是没有验证折扣语义。
- 测试曾在预期错误实现上失败
- 关键输出和副作用均有断言
- mock 没有替代被测逻辑
测试假通过怎么检查,先从“只断言状态或非空”这一类现象查起
只断言状态或非空
- 原因
- 断言过弱,错误内容仍满足条件。
- 怎么改
- 检查关键字段、业务不变量和副作用;用错误值验证断言真的区分。
Mock 了被测逻辑本身
- 原因
- 测试只验证自己配置的返回值。
- 怎么改
- 只替代真正外部边界,核心业务使用真实实现和可控输入。
异步任务没有等待
- 原因
- 测试在断言前结束,或异常未传播。
- 怎么改
- 等待实际完成条件,检查失败分支和未处理 Promise,避免固定 sleep。
选择器或用例没有执行
- 原因
- 测试被跳过、筛选错误或浏览器定位到错误元素。
- 怎么改
- 检查测试数量、跳过状态和定位唯一性;故意改页面文案确认用例失败。
复测前,固定原始现象、环境和目标
| 需要确认 | 本例内容 |
|---|---|
| 现有材料 | Node.js 20+;下面calculate函数与3条测试;折扣范围0到1。 |
| 不能越过的边界 | 先让测试在错误实现上失败;断言输出与副作用;不要断言 mock 自己配置的结果。 |
| 要交付的结果 | 失败注入结果与有效断言清单 |
完整实现与有效断言
calculate.mjs
示例契约
export function calculate(items, discount) {
if(discount<0 || discount>1) throw new Error('invalid discount');
return items.reduce((sum,x)=>sum+x.price*x.quantity,0)*(1-discount);
}calculate.test.mjs
3条Node测试
import test from 'node:test';
import assert from 'node:assert/strict';
import {calculate} from './calculate.mjs';
test('金额与输入不变',()=>{ const rows=[{price:100,quantity:2}]; assert.equal(calculate(rows,0.1),180); assert.deepEqual(rows,[{price:100,quantity:2}]); });
test('零折扣',()=>assert.equal(calculate([{price:100,quantity:2}],0),200));
test('超范围',()=>assert.throws(()=>calculate([],1.2),/invalid discount/));命令
红绿检查
node --test calculate.test.mjs # 临时把(1-discount)改为(1+discount),重跑应报180与220不符。 # 恢复减法,再跑同一命令。
assert.ok对180和220都会通过,对0失败。这里精确金额与输入不变断言才覆盖目标;若故障注入后仍绿,检查用例是否执行或被测函数是否被mock替代。
测试假通过怎么检查:按原条件复测的结果
原始现象
仅检查Boolean(total)无法区分180与220。
失败注入结果与有效断言清单
预期正确实现3条通过;临时将减法改加法后金额断言失败。这不是邮箱验证或保存副作用的测试。
让 AI 审查测试是否真的会失败
把实现、测试和真实业务规则一起给AI,重点找假断言和漏测边界。
可复制使用
让 AI 审查测试是否真的会失败
请检查现有测试是否真的能发现【业务行为】的回归。不要通过改实现让测试变绿。 实现文件【】;测试文件【】;业务规则及反例【】;测试命令和实际输出【】。 逐个测试说明它失败时能捕获什么错误。重点找没有断言、只验证 mock 被调用、断言固定常量、关键分支未进入或错误值也会通过的用例。提出一个最小反例/变异来证明测试会失败,并给补充测试草案。没有实际运行的部分标“建议未验证”;不得删失败测试或宣称测试通过。
使用范围:把实现、测试和真实业务规则一起给AI,重点找假断言和漏测边界。不为了通过测试修改业务行为,不删除失败用例,不声称未运行的测试已通过。
