Claude Code 修改了代码,然后说:"测试通过了"。这句话虽然简短,背后却有测试文件、运行命令和具体结果。先了解测试有哪些类型、哪些内容可以手动检查,再来看自动测试,以及它的结果意味着什么。
用一个积分计算的小例子就够了。您不必提前了解测试库:我们先手动走一遍场景,再为自动测试写出预期,最后读懂执行报告。

测试有哪些类型
测试可以帮助您了解程序如何运行、是否符合要求,以及问题出在哪里。比如,积分是否正确增加、空字段的申请能否提交、错误提示是否清楚。为此,需要设定检查条件、执行操作,再查看结果。
测试可以按不同标准分类。先看由谁执行操作并检查结果:
- 手动测试 - 人亲自完成检查,并判断结果如何;
- 自动化测试 - 将部分检查交给程序执行:程序会按要求完成操作并进行比较。这样的一项项检查通常称为自动化测试用例,或简称自动测试。

这是按执行方式进行的分类。还有一个问题:具体检查什么。功能测试关注程序的行为,比如是否增加了应得的积分。非功能测试关注应用的特性,比如响应速度和使用是否方便。这两个分类彼此独立:同一项功能既可以手动检查,也可以自动检查。
自动化并不会让人完全退出流程。您仍然要挑选有用的场景、设定预期,并分析发现的差异。只是重复性的工作交给了程序。
什么是手动测试
手动测试时,您亲自执行操作,并查看结果是否符合预期。不一定要编写测试代码。您需要的是明确的条件,以及一个想要回答的问题。
假设在一个教学平台上,每次匹配得 10 分,那么三次应得 30 分。可以这样手动检查积分:
- 打开对应版本的平台,准备一个余额为零、尚未获得奖励的用户;
- 准备一份包含三次匹配的申请,并提交一次;
- 查看提交后的余额:预期为 30 分;
- 记录实际结果。如果数字不符,保存操作步骤,必要时截屏。
这里的初始余额很重要。如果原来已有 20 分,增加积分后预期应该是 50 分,而不是 30 分。没有初始条件,就很容易把正确结果当成错误,或反过来。
您可以简短地记录检查结果:"提交前余额为 0,三次匹配,提交一次,预期 30 分,实际得到 3 分"。别人或 Claude Code 看了这条记录,就知道该如何复现。"积分好像不对"则说不清楚问题。
手动测试也可以是探索性的:您一边了解应用,一边想出新的检查点。比如发现提交后按钮仍然可用,于是决定检查能否再次点击。此时没有预先写好的逐步路线,但目标仍然明确:了解行为并记录发现的问题。不是随便点几下。
使用工具也完全没问题。您可以打开浏览器控制台、查看服务器响应、截图或维护检查清单。"手动"指由人控制检查过程并评估结果,并不是说不能使用工具。
手动检查适合探索新行为或判断界面是否易懂。自动检查适合反复执行已经描述好的操作和比较。这并不意味着"界面只能手动检查,计算只能靠代码":浏览器操作也可以自动化,计算结果也能手动核对。
点击自动测试的运行按钮,并不算手动测试:启动后,实际执行检查的是程序。如果 Claude Code 为您列出步骤,而您按这些步骤亲自在平台上走了一遍并评估结果,这仍然是手动测试。智能体只是帮您准备了检查流程。
什么是自动测试
想象一下,您在检查计算器。输入 2 + 2,预先知道答案应该是 4,然后把屏幕上的数字与预期比较。如果显示 5,就能确定这个例子的结果不正确。无论计算器显示什么,您都知道正确答案。
自动测试用程序完成类似的工作。它是一个小程序,会设定初始条件、执行操作并检查结果。比较工作由代码代替人来完成。下文将把这种自动测试简称为测试。
回到奖励平台:每次匹配得 10 分,三次应得 30 分。可以用文字描述这项检查:
- 准备匹配次数:3;
- 计算奖励;
- 检查奖励是否为 30 分。
这就是一个测试。它包含一个已知示例和预期答案。"每次匹配得 10 分"是我们这个教学平台的规则;其他应用的规则可能不同。
测试不会自行推断用户应该得到多少积分。必须有人依据需求写下预期结果。可以由开发者来做,也可以按您的要求让 Claude Code 来做,但仍要核对预期是否符合任务。
为什么要重复检查
手动检查一次积分计算并不麻烦。问题出现在之后:您添加了新的奖励类型、修改了申请处理逻辑,或让智能体简化了函数。每次修改后,都要再次回答同一个问题:三次匹配仍然会得到 30 分吗?
您可以每次重新准备申请、执行操作并查看结果,也可以把检查写进代码,以后反复运行。只要准备条件相同,测试就会重复执行指定的操作和比较。您不必每次重新解释该点哪里、什么才算正确。
随着项目发展,这类规则会越来越多。没有匹配时不应增加积分;重复提交不能重复计算;奖励列表应按指定顺序排列。您可以一起运行这些检查,并看到修改后哪些预期不再成立。
这就是自动化的价值:重复检查已描述的行为,可以减少手动工作。编写测试也要花时间,需求变更后还得重新审视测试。不过,对于经常要核对的规则,这份投入能通过反复运行测试得到回报。
测试文件放在哪里
测试保存在项目的普通文件中。在较小的 JavaScript 项目里,可以把测试放在它所调用的代码旁边:
reward-example/
├── package.json
└── src/
├── reward-flow.js
└── reward-flow.test.jsreward-flow.js 中是奖励计算逻辑。reward-flow.test.js 中的代码会调用该逻辑并检查结果。package.json 文件描述项目配置和命令,其中也包括测试命令。
文件名中的 .test.js 可以帮助您识别测试文件。这是测试工具支持的一种命名约定,并非 JavaScript 语言自身的规则。其他项目可能使用不同的名称,或单独设一个 tests/ 文件夹。一个文件可以包含多个测试;并不要求每个源文件旁边都有单独的测试文件。
如果 Claude Code 正在处理一个陌生项目,可以先让它找到现有的积分测试,并给出文件路径。这样即使您还不熟悉所有文件夹,也能把测试和需要检查的行为对应起来。
如何把意图转化为检查
"修复积分计算并用测试检查"这样的要求,会让智能体面对两个问题:怎样才算正确计算,以及用什么来确认结果。不妨先描述您期望看到的行为。例如:"每次匹配应得 10 分。三次匹配时,奖励应为 30 分。"
不写一行代码,也能把这样的意图变成检查。只要说明三件事:
| 需要设定什么 | 问问自己 | 示例 |
|---|---|---|
| 初始条件 | 操作前已知什么? | 结果中有三次匹配;每次应得 10 分 |
| 操作 | 具体要检查什么? | 计算这次结果对应的奖励 |
| 预期 | 观察到什么才算正确? | 奖励为 30 分 |
可以把它连成一句话:"如果有三次匹配,计算奖励时应得到 30 分。"这些信息足以讨论测试的含义。至于在这个项目中要用什么代码来实现,智能体可以处理。
关键是要选准要确认的内容。"算出的奖励是 30"与"用户余额变成了 30"是两种不同的预期。第二种还需要初始余额和增加积分的操作,就像前面的手动检查。因此,与其说"检查积分",不如描述具体要观察什么。
接着想想相关的其他情况。按照我们的规则,可以先列一个小表:
| 情况 | 预期结果 | 检查目的 |
|---|---|---|
| 三次匹配 | 奖励 30 分 | 检查本次修复针对的场景 |
| 零次匹配 | 奖励 0 分 | 检查没有匹配时的行为 |
| 五次匹配 | 奖励 50 分 | 按同一规则再检查一个数值 |
不必一开始就列出几十种情况。先从出问题的场景,以及修改可能影响到的几个相邻场景入手。如果某件事的规则还不清楚,比如重复提交应该怎样处理,就先把规则问清楚。智能体可以提出方案,但那还不等于已经确认了预期。
可以先让 Claude Code 在修改前列出各种情况和预期结果。看这份清单时,您更容易发现智能体检查了错误的操作、漏掉了重要条件,或是自行编造了规则。此时修改几句话,比拿到针对其他目标的测试后再排查要容易得多。
如何让 Claude Code 执行检查
描述清楚预期行为后,就可以围绕它安排工作。智能体先查看项目已有的检查,再逐项对照您的场景。需要的测试可能已经存在,这时要运行它并查看结果。如果还没有,智能体就需要添加测试。
可以这样提出第一项要求:
修复奖励计算。
规则:每次匹配增加 10 分。
要检查的情况:3 次匹配得到 30 分,
0 次得到 0 分,5 次得到 50 分。
修改前,先找出这些情况已有的检查。
简要说明哪些情况已经覆盖、还缺少什么,
以及您建议添加或修改哪些测试。
如果需求有不清楚的地方,请指出来。
先不要修改文件。把回复当作未来结果的描述来读。每种情况的数字都来自您的规则吗?检查的是奖励分数,还是其他内容?智能体有没有建议修改规则,好让当前行为看起来符合要求?此时您是在明确任务,不需要阅读测试实现。
场景确定后,再让智能体开始执行:
按照讨论好的规则修复计算。
使用项目现有的工具,为确认过的场景
补充缺少的检查。
不要为了让测试通过而修改已有预期。
如果您认为预期有误,请先说明原因。
按照项目说明运行需要的测试。
展示运行命令、工作目录和实际输出。
对三个场景分别说明由哪个测试检查,
以及测试结果。单独列出跳过和未运行的检查。智能体会从项目文档和配置中查找运行命令。在 JavaScript 项目中,常见命令是 npm test:npm 会执行文件 package.json 中 scripts.test 字段指定的命令。这个名称背后可能对应不同的一组检查。您要确认的是,本次运行确实包含了需要的场景。
编写测试和运行测试是两件不同的事。"添加了三个检查"只说明文件发生了变化。要评估结果,就得实际运行。如果由于缺少依赖等原因无法运行,智能体应该说明障碍,以及哪些检查还没有执行。
在回复中寻找这条对应关系:"我们的场景 → 具体测试 → 结果"。如果讨论过的三个场景只运行了一个,目前也只有这一个得到验证。即使最后一行显示绿色,也一样。
如何阅读测试结果
下面展示的是在 Node.js 20.18.0 和 npm 10.8.2 上实际运行一个教学测试的结果。它只检查三次匹配对应的奖励计算,并未覆盖上面列出的所有场景。为了便于阅读,这里省略了时间行和报告中的辅助信息:
> reward-example@1.0.0 test
> node --test --test-reporter=tap
# Subtest: three matches give 30 points
ok 1 - three matches give 30 points
# tests 1
# suites 0
# pass 1
# fail 0
# cancelled 0
# skipped 0
# todo 0前两行显示软件包和执行的命令。下面是测试名称。ok 1 表示第 1 个测试通过;失败的测试则以 not ok 开头。pass 1 和 fail 0 表示一个测试通过,没有测试失败。这就是所谓的"绿色"结果,即使终端没有给文字着色。
在有错误的版本中,三次匹配只得到 3 分,但规则要求 30 分。同一个测试会输出下面这段内容;这里省略了路径、调用栈、时间和部分辅助信息:
not ok 1 - three matches give 30 points
error: |-
Expected values to be strictly equal:
3 !== 30
code: 'ERR_ASSERTION'
name: 'AssertionError'
expected: 30
actual: 3
operator: 'strictEqual'
# tests 1
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0先找到测试名称,再比较 expected 和 actual。前者表示"预期值",后者表示"实际值"。这里预期是 30,实际是 3。fail 1 则总结了结果:一个测试失败。
测试失败表示实际结果与记录的预期不一致。接下来要查明原因:计算错误、初始数据不正确,还是测试本身的预期有误。不能只为让报告通过就修改检查中的数字;应先核对任务规则。
还有一种失败情况,比如测试无法导入函数文件。这样它根本还没比较积分,报告里甚至可能看不到具体测试的名称,因为标记失败的是整个文件。因此,光看一行 fail 1,不足以断定"计算错了"。还要查看总结前面的错误信息。
被跳过的测试
测试还有一种重要状态:检查可能被标记为跳过。例如,在 Node.js 中可以使用 test.skip。这类测试不会执行。报告中出现了测试名称,并不代表相应场景真的经过了检查。
单独运行本例时,被跳过的测试会显示如下行和统计结果:
ok 1 - three matches give 30 points # SKIP
# tests 1
# pass 0
# fail 0
# cancelled 0
# skipped 1
# todo 0请留意一个不太直观的细节:这一行以 ok 开头,却以 # SKIP 结尾。这种格式就是这样标记跳过的。不能只看第一个词;统计结果 pass 0 说明没有任何测试通过。
把同一场景的三种运行结果放在一起看:
| 状态 | pass | fail | skipped | 可以确定什么 |
|---|---|---|---|---|
| 通过 | 1 | 0 | 0 | 三次匹配的检查得到了预期的 30 分 |
| 比较失败 | 0 | 1 | 0 | 实际数字与 30 不符 |
| 跳过 | 0 | 0 | 1 | 此测试没有检查计算结果 |
较大的报告中还会有其他行。在我们的运行结果中,cancelled 和 todo 都是零。如果看到非零值,就要查清有哪些测试被取消或标记为未完成,不能把它们算作已成功检查。suites 表示测试组:本例中没有测试组。
还有个小细节:如果报告显示测试数量为零,没有失败并不能证明积分正确。需要的检查可能根本没有运行。与终端颜色带来的整体印象相比,场景名称和已执行检查的数量更重要。
绿色结果意味着什么
报告中的测试只回答了一个具体问题:"三次匹配时,奖励计算正确吗?"它没有检查零次匹配、重复申请,或页面上显示的积分。即使我们在任务要求中提到了这些场景,也不代表它们已经经过检查。
要检查零次匹配,还需要另一个场景,并单独设定预期值 0。要检查重复申请,则必须明确描述重复操作以及预期结果。测试不会从相邻代码中猜出这些规则。它只会检查自己记录的内容。
没有编写测试和跳过测试是两回事。被跳过的测试会在报告中显示为 skipped。至于根本没有编写检查的场景,报告通常不会提到。即使未检查的行为中存在错误,现有测试也可能全部通过。
最后,比较成功并不能说明预期本身正确。如果按照我们的规则,错误地把预期写成 3 而不是 30,而计算结果恰好是 3,那么比较仍然会通过。因此,讨论检查时最好回答两个问题:测试检查了什么行为?预期结果是根据什么得出的?
理解了边界,"测试通过了"这句话才有意义。它表示特定的一组检查在特定的一次运行中成功完成,但不能据此保证"应用中再也没有错误"。
GO TO FULL VERSION