收益:
- 能够通过 AI 进行有意义的断言来生成单元、集成和边缘案例测试
- 能够在人工智能的支持下系统地提取测试覆盖率、极限值和负面场景
- 能够验证人工智能生成的测试是否确实验证了行为,而不仅仅是重复现有代码
测试是证明软件确实按照承诺运行的机制。一个好的测试套件可以在几秒钟内告诉您更改是否会破坏某些内容,并让工程师可以自由地自信地采取行动。人工智能加快了测试编写中最乏味和最容易被跳过的部分:生成大量场景、断点和负面案例。但这里有一个狡猾的陷阱:人工智能可能会编写测试来验证代码的当前(可能是错误的)行为,而不是其假定的行为;或者它可以生成总是通过的空测试,而不实际检查任何内容。测试的价值不在于它是否通过,而在于它是否检查正确的事情并在错误时变红。
在本单元中,您将学习如何使用有意义的断言来生成单元、集成和边缘案例测试;如何系统地提取测试覆盖率、断点和下行场景;我们将了解如何检查人工智能生成的测试是否确实验证了行为。
概念: 单元测试:单独测试单个函数/类。集成测试:测试多个部分是否正确协同工作。 Assert:检查结果是否等于预期的语句;这是测试的核心。覆盖率:测试运行了多少代码;高覆盖率并不能保证质量。
进行有意义的测试
一个好的测试清楚地做三件事:它建立一个状态,它执行一个动作,它断言结果。当向 AI 打印测试时,指定要验证什么行为以及它应该涵盖哪些场景;否则,它会产生总是通过的肤浅测试。
- 定义要测试的行为。 “什么才是正确的?”清楚地回答问题。
- 询问场景类型。正常、极限、负值、错误条件。
- 导入有意义的断言。它不只是“抛出错误”,它“返回正确的值”。
- 检查测试的准确性。当你有意识地破译代码时,测试会变红吗?
综合测试生成提示:“为以下 'applydiscount(amount, coupon)' 函数编写单元测试。在以下类别中至少有一种场景:(1) 正常有效优惠券,(2) 断点(0 金额,100% 折扣),(3) 负数(无效优惠券,负数),(4) 错误情况(空优惠券)。在每个测试中断言具体的预期值(不仅仅是“有效”)。为测试命名可读。代码:[代码]”
边界值提取提示:“对这个函数的输入进行边界值分析。对于每个参数,提取‘刚好在边界处’、‘刚好在边界之下’、‘刚好在边界之上’的值作为表格。然后列出覆盖这些边界的测试场景。先不要写代码,只需分析和场景列表。功能:[签名]”
注意:高测试覆盖率(例如 90%)并不能证明代码是正确的。覆盖率衡量执行了多少行;并不是说这些行产生了正确的结果。没有有意义的断言的测试会增加覆盖范围,但不能保证任何事情。断言的内容决定质量,而不是断言的数量。
测试测试本身:突变的逻辑
了解人工智能生成的测试是否真正有效的最实用方法是故意破坏代码(突变测试逻辑)。反转条件,制作+号-;如果没有测试变红,则您的测试实际上并未维持该行为。
测试漏洞搜寻提示:“告诉我以下测试可能无法捕获此代码中的哪些潜在错误。建议可以对代码进行 5 个小更改(例如 >= 代替 >,- 代替 +),并为每个更改指出现有测试是否会捕获它。对于那些未捕获的,建议应添加测试。代码:[code] 测试:[test]”
弱提示/强提示
弱:“为此函数编写测试。” (结果:通常是一种愉快的场景,弱断言;错过错误。) 强:“为此 'passwordStrong' 函数编写一个测试。规则:至少 8 个字符,1 个大写字母,需要 1 个数字。将以下场景作为单独的测试进行覆盖:正好 8 个字符(限制)、7 个字符(低于限制)、没有大写字母、没有数字、空字符串、只有空格、太长(1000 个字符)显式断言预期的 true/false 值在每个测试中,并根据它检查的内容来命名测试。”
强大的提示给出了规则和完整的边界场景。像“恰好 8 / 7 个字符”这样的边界对是最容易出错的地方(将 > 与 >= 混淆)。弱提示绕过了这些边界并将错误带入生产环境。
测试类型和使用地点
测试类型
它证实了什么?
人工智能贡献
注意
单位
单一功能/类
快速生成多场景
需要有意义的断言
整合
部件协同工作
场景和模拟数据草稿
真正的成瘾行为
结束/接受
整个用户流程
步骤清单和期望
容易脆化
回归
旧错误未返回
故障具体测试
应该添加到每个修复中
迷你箱
案例 1——总是通过的测试。 AI 为一个函数编写了 12 个测试,并且全部通过。工程师产生怀疑并故意歪曲函数的返回值;只有 3 个测试变成红色。其他 9 个测试不包含有意义的断言。通过突变狩猎加强测试;真正的保护是在 9 个场景中获得的。
情况 2 — 边界错误。年龄验证功能应显示“18 岁及以上有效”,但写入的是 >18,这意味着 18 岁被拒绝。该错误在测试中立即出现,因为 AI 通过断点分析生成了“恰好 18”的场景。单一极限测试可以防止任何真正的用户投诉。
案例 3 — 修复当前行为。当人工智能被告知“基于此代码编写测试”时,它会生成一个测试,该测试接受代码中已存在的舍入错误为“正确”。当工程师按照要求(预期正确值)而不是代码打印测试时,测试变成红色,真正的错误发生。测试应该源自期望,而不是源自代码。
常见错误
- 毫无意义的断言。 “没有抛出错误”是不够的;必须验证正确的值。
- 混淆范围和质量。高覆盖率并不能保证结果准确。
- 通过代码打印测试。将当前错误修复为“true”;测试应该源自期望。
- 跳过极限值。将 > 与 >= 混淆是最常见的错误;必须测试边界对。
- 不审核测试本身。当您破坏代码时不会变红的测试不能提供保护。
综上所述
良好的测试套件是充满信心地进行更改的关键。人工智能快速生成大量场景、边界和负面情况;但如果它从代码而不是需求中派生测试,它就可以修复现有的错误或编写总是通过的无意义的测试。在每个测试中断言具体的预期值,包括绑定对,并通过故意破坏代码来验证您的测试是否确实提供了保护。断言的内容,而不是范围的数量,决定了质量。
应用任务
选择一个函数并让它生成四个类别的测试(正常、极限、负数、错误),并带有全面的测试生成提示;在每次测试中断言具体的期望值。然后运行测试漏洞搜寻提示,建议代码中的 5 个小突变,并运行测试以检查它们捕获了哪些突变。为至少一个未捕获的突变添加新的测试,并显示它现在处于红色状态。
清单
- [ ] 我根据预期/正确的行为打印了测试,而不是代码。
- [ ] 我涵盖了正常、限制、负面和错误场景。
- [ ] 我在每个测试中断言了具体的期望值。
- [ ] 我测试了边框对(就在上面-下面/就在上面-下面)。
- [ ] 通过故意破坏代码,我确认测试变成了红色。
- [ ] 我添加了针对未检测到的突变的新测试。