先看仓库,再谈Jest

当前AI编码代理通常能产出Jest语法。它们可以快速写出describe、test、expect、mock和fixture。这已经不是最难的部分。

打开网易新闻 查看精彩图片

难的是得到一个真正属于仓库、并保护关键行为的测试。代理可能为一个错误的边界写出完全有效的测试,把风险mock掉,或者报告一个通过的命令,却远没有评审者以为的那么有证明力。

因此提示词应当定义一个测试工作流,而不只是索要测试代码。作者使用的顺序是:上下文、风险、一次聚焦实现、对抗性挑战、证据报告。

第一道闸门:先摸清现有测试系统

在要求代理安装Jest或创建测试之前,先让它梳理现有测试体系。这很重要,因为Jest未必是正确的运行器。前端工作区可能已经在用Vitest,Node项目可能使用内置测试运行器,monorepo可能在不同包中使用不同运行器。

当Jest确实合适时,其官方配置参考应作为版本特定选项的来源,而不是依赖记忆中的配置配方。

作者给出一个禁止编辑的检查提示词:在改动前检查此仓库,确定包管理器、语言和模块系统;是否为monorepo以及哪个工作区拥有目标;当前测试运行器、库、命令和CI设置;Jest是否已安装及如何配置;最近的测试、fixture、工厂和命名约定;任何TypeScript、ESM、路径别名、DOM或转换要求。最后报告Jest是否适合目标、最小安全推进路径,以及需要作者做出的决定,并且不要编辑文件。

第一响应就是一道闸门

如果代理建议把Jest加到一个已有既定运行器的工作区,就要让它说明运营成本。正确的结果可以是决定不使用Jest。

持久化仓库指令也因代理而异。Codex读取分层的AGENTS.md文件,Claude Code支持CLAUDE.md和作用域规则,Cursor使用.cursor/rules下的项目规则,GitHub Copilot支持仓库和路径特定指令,具体支持取决于环境。文章中的提示词是可移植的,但仍需确认所选代理实际加载了什么。

第二道闸门:先要行为与风险计划

“为这个文件写测试”给代理的是文件边界,而不是质量标准。它可以通过测试getter、复制实现分支或断言mock被调用来给自己奖励覆盖率。

作者建议在写代码前先要计划:为某功能、模块或变更规划Jest测试,先不要写代码。阅读实现、调用方、附近测试以及相关产品或API文档。对每个拟议用例,报告可观察行为或契约、失败为何重要、正常边界和错误用例、正确的测试层级(单元、集成、契约或端到端),以及依赖项。

把风险写进计划,而不是留给代码

计划阶段要求代理明确哪些行为值得保护。一个测试如果只验证实现细节,改动一行代码就可能失效;如果验证的是对外契约,重构时仍能站住。

作者强调,代理需要区分“测试通过”和“测试证明”。一个mock掉外部依赖的测试可能永远通过,却无法捕获真实集成中的失败。因此计划中要写清哪些依赖可以mock,哪些必须真实。

第三道闸门:一次只做一个聚焦实现

拿到计划后,不要让代理一次性铺开全部用例。先让它实现一个最能代表核心契约的测试,运行并确认失败原因,再继续。

这样做的目的是防止代理用大量低价值测试淹没评审。一个聚焦实现能让人看清代理是否理解了边界,而不是在凑数量。

第四道闸门:对抗性挑战

测试写完后,让代理扮演反对者:这个测试在什么情况下会给出虚假信心?哪些输入会让它误判?如果删掉实现中的关键逻辑,测试还会通过吗?

作者把这一步称为对抗性挑战。它要求代理主动寻找自己测试的盲点,而不是只报告绿色通过状态。

第五道闸门:证据报告

最后一步不是简单贴出测试结果,而是要求代理报告:运行了什么命令、哪些测试通过或失败、失败原因、覆盖率变化,以及最重要的——这个测试实际保护了什么行为。

证据报告让评审者不必自己翻看代码就能判断测试价值。它把“能跑”的测试和“值得留”的测试区分开来。

工作流的核心不是Jest

这套五道闸门工作流的关键在于,它把AI代理从“测试代码生成器”变成“测试决策参与者”。上下文、风险、聚焦实现、对抗挑战和证据报告,每一步都在逼代理回答同一个问题:这个测试为什么值得留在仓库里。

对科技团队来说,这比纠结于Jest还是Vitest更重要。工具会变,但判断测试价值的流程可以复用。