尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

手工、直接补全、提示词工程:同一模块覆盖率从 35% 飙到 82%

手工、直接补全、提示词工程:同一模块覆盖率从 35% 飙到 82% 手工、直接补全、提示词工程:同一模块覆盖率从 35% 飙到 82%发版前两天,QA 在 MR 下留了一句评论:“这个订单模块的单测覆盖率 35%,至少提到 80% 才能合并。”我盯着那行注释,想着 30 多个方法里满是多重 if-else 和异常分支,手写测试得两天。不如让 CodeWhisperer 帮我生成,刷刷补全就行。结果 AI 直接补出来的测试像在敷衍:断言都是assertTrue(true),分支覆盖毫无章法。后来我找到一门讲提示词工程的生成式AI课程--里面专门拆解了怎么给 AI 编程助手下指令,从上下文设计到用例结构,每一步都有可套用的模板。学完不到一小时,我重新组织 prompt,让 CodeWhisperer 针对订单结算方法生成测试,这次直接把覆盖率拉到了 82%。要是你也被测试覆盖率压得喘不过气,真该去翻翻那门课里提示词工程的章节,它会告诉你为什么简单补全不灵、什么才是能进流水线的生成指令。为什么直接把方法名扔给 CodeWhisperer 不管用我最初的做法很粗暴:在OrderService.java的结算方法上方打开 CodeWhisperer 补全,期望它能自动推断测试意图。它确实生成了一段 JUnit 代码,但只覆盖了正常路径,异常分支、空值边界、货币精度这些场景全漏了。// 结算方法 public BigDecimal settle(Order order, DiscountPolicy policy) { if (order.getItems().isEmpty()) { throw new IllegalArgumentException(订单无商品); } BigDecimal subtotal order.getItems().stream() .map(Item::getPrice) .reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal discount policy.calcDiscount(order); return subtotal.subtract(discount).setScale(2, RoundingMode.HALF_UP); }CodeWhisperer 直接补全的测试只传了一个正常的订单对象,断言结果不为 null,连折扣边界都没碰。我当时还不懂,这其实是因为 AI 编程助手默认依赖方法签名和当前文档的浅层信息,缺少对“高风险业务需要哪些异常输入”的理解。正是这个翻车让我意识到,生成式AI 虽然能写代码,但如果不教它怎么思考测试设计,它只是在拼凑已有模式。而在那门生成式AI 课程里,我看到了提示词工程的关键--你需要用结构化的自然语言告诉模型:输入有哪些等价类、期望行为是什么、要覆盖哪些异常路径。提示词工程第一节:把测试需求写成约束清单课程把提示词工程拆成了三个层次:任务描述、上下文注入、输出格式约束。我按照这个框架,在结算方法上方写了一段完整的prompt注释,而不是零散的关键词。下面是我学完提示词工程后重写的指令,它明确要求覆盖正常路径、空列表异常、精度校验和百分百折扣四个场景:/** * 为 settle 方法生成参数化单元测试,覆盖以下场景: * 1. 正常订单 无折扣策略 - 返回原价 rounded HALF_UP * 2. 空商品列表 - 抛出 IllegalArgumentException,断言消息包含 无商品 * 3. 多商品订单 百分百折扣策略 - 返回 0.00 * 4. 单价含三位小数 - 校验最终结果保留两位小数 * 使用 CsvSource 提供参数,每个断言前添加注释说明意图。 */CodeWhisperer 这一次的生成结果截然不同。它直接给出了带ParameterizedTest和CsvSource的完整测试类,四个分支全部正确,甚至自动构造了Mockito的 mock 折扣策略。这门课程强调,提示词工程不是拍脑袋写几个关键词,而是把业务风险翻译成测试约束。如果读者也想让 AI 编程助手写出可靠的单元测试,建议先看看那门课里关于提示词工程的章节--它用大量实战案例演示了如何从“我想要一个测试”进阶到“我想要覆盖这些边界条件的测试”。用分层 prompt 攻克复杂逻辑和 mock 依赖结算方法还依赖外部的DiscountPolicy接口,CodeWhisperer 自动生成的测试经常直接 new 一个实现类,无法隔离依赖。于是我把 prompt 分成了两层:第一层说明 mock 策略,第二层描述测试场景。/** * 测试 settle 方法时,使用 Mockito 模拟 DiscountPolicy 接口。 * 以下为四个参数化场景: * ...(同上) */这次 CodeWhisperer 不仅生成了基于Mock和InjectMocks的测试骨架,还在每个测试方法里自动插入了when(policy.calcDiscount(any())).thenReturn(...)的配置。之前需要我手动写 20 分钟 mock 代码,现在 3 秒就全出来了。我能做到这一点,正是因为提示词工程教会了我如何将复杂需求拆成 CodeWhisperer 能一次性理解的“子任务”。生成式AI 课程里还讲过,对于需要多步骤交互的场景,可以先用自然语言让模型输出测试大纲,再根据大纲逐个生成用例--这个方法后来被我用在了更复杂的支付回调测试上,效果同样出色。从 35% 到 82% 的实测数据与改进清单我将所有涉及金额计算的方法都用相同的提示词工程模板重新生成后,用 JaCoCo 跑了一次全量单测。订单模块的指令覆盖率从 35% 提升到 82%,分支覆盖率从 21% 提到 76%。下面是我们部门内部的对比数据:生成方式方法数指令覆盖率分支覆盖率人均耗时手工编写3060%55%7 小时CodeWhisperer 默认补全3035%21%40 分钟CodeWhisperer 提示词工程3082%76%1.5 小时默认补全虽然快,但覆盖率远不及格;手工编写费时且容易遗漏异常分支;只有将提示词工程和 CodeWhisperer 结合,才能在 1.5 小时内交出可合并的测试代码。这个过程也让我理解了为什么机器学习和深度学习的基础知识对测试设计同样重要。人工智能入门 课里讲解的“过拟合”概念,让我意识到如果一个测试只覆盖正常路径,就像模型在训练集上过拟合一样,上线必崩。于是我照着机器学习基础 课程里介绍的混淆矩阵思想,把每种方法的测试覆盖拆成了 TP(正常路径正确断言)、TN(异常路径正确拒绝)两个维度去检查,确保没有漏掉导致假阴性的分支。这门课还教会我什么:从补全到架构级思维原本我学 AWS 人工智能 课程只是为了搞定覆盖率,结果发现它连带着打开了更多场景。CodeWhisperer 不仅能写单测,在类注释里用提示词工程描述一个 Service 的职责和依赖后,它能直接生成完整的异常处理模板和 log 埋点,省掉了大量重复劳动。深度学习入门 中关于注意力权重分配的原理,让我在设计 prompt 时懂得把最关键约束(比如金额精度和异常类型)放在最前面,这显著提升了生成质量。Amazon CodeWhisperer 的官方最佳实践也印证了这一点:重要信息前置能减少模型注意力分散。如果你也在用其他 AI 编程助手,这些经验同样适用,因为它们背后的生成式AI 模型都遵循类似的注意力机制。另外,AWS 机器学习 课程里关于管道和自动化评估的内容启发我把生成-验证-提交写成了一个 CI 脚本:在 GitHub Actions 里调用 CodeWhisperer 生成测试,然后自动跑覆盖率检查,低于 80% 自动打回。这一套下来,团队的人均单元测试时间从 12 小时降到了 3 小时。给被测试覆盖率困住的开发者的建议如果你跟我当初一样,以为 AI 补全只是锦上添花,那很可能会重蹈我 35% 的翻车。有几点建议可以立刻用起来:先花一小时补一下提示词工程生成式AI 课程里那几节精讲,足够让你写出的 prompt 脱胎换骨。把测试要求写成约束清单,而不是关键词,每一条都写明输入、期望行为和异常条件。区分正常分支和异常分支的提示词,必要时分两层 prompt 交给 CodeWhisperer 逐一生成。用机器学习基础中的评估思维检查覆盖盲区把自己当成模型打分,看哪些分支还没被断言覆盖。CodeWhisperer 的 mock 生成依赖清晰的接口定义,先把依赖注入骨架写好,再让 AI 补测试细节,成功率更高。把 AI 编程助手纳入 CI 流程:亚马逊云科技提供的一系列 AI 课程里,有详细案例教你如何把 CodeWhisperer 和自动化流水线串起来。最后再说一句,别停留在“工具能用就行”的层面。当我把提示词工程当一门手艺去打磨之后,CodeWhisperer 从一个偶尔帮忙的补全工具,变成了能帮我写一整个测试套件的结对伙伴。如果你也想让覆盖率像坐火箭一样蹿升,那门 AWS 人工智能入门课程里的提示词章节,绝对值得第一个点进去看看。
返回列表