CTest 怎么只重跑上次失败的测试
来源:17golang原创
时间:2026-10-13 06:55:22 459浏览 收藏
CTest 支持直接重跑上一轮失败的测试:在已经执行过完整测试的构建目录中运行 ctest --rerun-failed 即可。它会把测试集合缩小到上次失败的项目,不需要把已经通过的用例再跑一遍;如果这次失败输出需要展开,再附加 --output-on-failure。
官方地址:https://cmake.org/cmake/help/latest/manual/ctest.1.html
最稳妥的使用顺序是:进入正确的构建目录,先完整运行一次 CTest,确认出现失败后,再执行 ctest --rerun-failed --output-on-failure。不要把它当作正则筛选开关,因为 CTest 会忽略其他用于改变测试集合的选项。
先把测试入口和构建目录对上
CTest 读取的是构建树里的 CTestTestfile.cmake。因此“只重跑失败测试”的第一步不是勾选某个选项,而是确认测试面板使用的构建目录,和上一次完整测试写入失败记录的目录相同。
# 进入 CMake 生成的构建目录,不要在源码目录凭空执行 cd build # 查看当前目录是否包含 CTest 的测试入口文件 test -f CTestTestfile.cmake && echo "测试入口已找到" # 先列出测试数量,确认面板和命令行指向的是同一棵构建树 ctest --show-only=human
如果你在 IDE 或构建工具面板里操作,先打开“测试 / Tests”区域,再确认“构建目录 / Build directory”字段。图中的界面是帮助定位字段的原创示意,不代表真实 CMake 或某个 IDE 的截图。

- 在左侧项目区域打开“测试 / Tests”。
- 在构建目录字段确认当前目录包含测试生成文件。
- 先选择“运行全部测试 / Run all tests”,让 CTest 产生本轮结果。
- 看到失败计数后,再把运行模式切换为“仅重跑失败 / Rerun failed”。
先完整运行一次,让 CTest 记住失败集合
--rerun-failed 不是凭空发现失败用例,它依赖此前一次 CTest 运行留下的失败结果。第一次排查时先运行完整集合,并用 --output-on-failure 把失败测试自己的输出显示出来。
# 第一次运行完整测试集,并在失败时直接展开测试程序输出 ctest --output-on-failure # 用退出码判断整轮是否有失败;失败时保留终端日志供下一步定位 test "$?" -eq 0 && echo "全部通过" || echo "存在失败测试,请执行仅失败重跑"
这里的完整运行承担两个作用:给出当前测试总结果,同时留下下一次 --rerun-failed 需要的失败集合。若所有测试都通过,就没有“需要缩小”的失败集合,应该把这一轮视为正常验收,而不是强行重跑。
用一个命令只重跑上次失败的测试
确认上一轮确实有失败后,直接在同一个构建目录执行下面的命令:
# 只重跑上一轮失败的测试,并保留失败测试的详细输出 ctest --rerun-failed --output-on-failure
这条命令的重点是“失败集合”,而不是测试名称。上一轮已经通过的测试不会因为这次重跑而重新执行,特别适合先修一个用例、再快速确认修复是否有效的循环。
CTest 官方说明还特别强调,指定 --rerun-failed 后,-R、-E、-L、-I 等用于改变测试列表的选项会被忽略。本文不把这些筛选正则和失败记录混用:需要按名称筛选时,应回到单独的测试选择命令。

把输出、退出码和下一轮对象分开看
排查时容易把“有输出”和“命令失败”混成一件事。--output-on-failure 只负责在测试失败时显示测试程序输出,不能改变 CTest 的选择范围。只要至少一个测试失败,CTest 的退出码就是非零;全部通过时退出码为 0。
# 将结果保存到日志文件,便于在面板外复查本轮重跑内容 ctest --rerun-failed --output-on-failure --output-log rerun-failed.log # shell 中用最后一条命令的退出码决定流水线是否继续 if [ "$?" -eq 0 ]; then echo "失败集合已经全部通过" else echo "仍有失败项,保留日志并继续修复" fi
如果修复后仍有失败,下一次调用会继续围绕最近失败的集合工作;如果本轮全部通过,就可以回到完整测试命令,确认没有遗漏此前没有执行的测试。
三个最容易误判的状态
| 看到的状态 | 实际含义 | 下一步 |
|---|---|---|
第一次直接执行 --rerun-failed | 没有可用的失败记录,可能不会执行你期待的测试 | 先在同一构建目录运行完整测试 |
| 上一轮全部通过后仍执行重跑 | 没有新的失败项可供缩小集合 | 回到完整测试或结束本轮验收 |
| 重跑数量和预期不一致 | 当前目录与之前运行的构建目录不一致,或测试生成文件已经更新 | 核对测试面板的构建目录和 CTestTestfile.cmake |
尤其要注意构建配置。Debug 和 Release 可能使用不同的构建目录,失败记录也不应跨目录猜测。把“记录属于哪棵构建树”先确认清楚,通常比不断添加命令行参数更有效。
在测试面板里固定一条可复用的操作路径
如果团队主要通过软件界面运行测试,可以把操作固定成一条短路径:先选择构建目录,再运行全部测试,失败后选择仅失败重跑,最后打开失败输出并查看结果日志。界面中的字段名称应服务于这四个动作,不要把“按名称筛选”和“重跑失败集合”放在同一个开关里。
- 打开“测试 / Tests”面板,选择本次构建配置。
- 点击“运行全部 / Run all”,等待失败计数落定。
- 点击“仅失败 / Rerun failed”,必要时打开“失败输出 / Output on failure”。
- 看到失败计数为零后,再决定结束验收还是回到完整测试。
常见问题
为什么第一次运行 ctest --rerun-failed 没有按预期执行?
它需要此前一次测试运行产生的失败集合。先在目标构建目录执行完整测试,再执行仅失败重跑。
--rerun-failed 能不能和 -R 一起限制测试名称?
不建议这样理解。官方文档说明,启用 --rerun-failed 时,其他用于修改测试列表的选项会被忽略。按名称筛选应单独使用测试选择命令。
重跑后全部通过,下一次还要继续执行 --rerun-failed 吗?
如果没有新的失败,通常没有必要继续重复重跑。回到完整测试做一次整体确认,或者结束当前修复循环。
最后只核对这四项
- 当前命令执行在正确的构建目录,能找到
CTestTestfile.cmake。 - 已经先运行过一次完整测试,并确实产生了失败集合。
- 重跑命令使用
ctest --rerun-failed --output-on-failure,没有把它误当成正则筛选。 - 根据新的退出码和失败计数决定继续修复、回到完整测试,还是结束验收。
-
Golang · Go教程 | 4个月前 | 超时控制 · 故障排查 · Go教程 · 后端工程 · Golang实战 · HTTP客户端 · golang Go 性能优化 net/http context Transport 超时 http.Client 生产实践205 收藏
-
Golang · Go教程 | 3个月前 | 并发 · HTTP · 性能优化 · 故障排查 · Go教程 · Go Goroutine 连接复用 pprof http.Client close Response.Body201 收藏
-
Golang · Go教程 | 2个月前 | golang · JSON · 故障排查 · Go教程 · 接口设计 · JSON Go 接口兼容性 DisallowUnknownFields 严格解码174 收藏
-
423 收藏
-
Golang · Go教程 | 1个月前 | golang · 服务端 · 故障排查 · net/http · 连接泄漏 StateIdle ConnState Go net/http StateHijacked311 收藏
-
370 收藏
-
470 收藏
-
392 收藏
-
378 收藏
-
202 收藏
-
415 收藏
-
490 收藏
-
450 收藏
-
222 收藏
-
331 收藏
-
254 收藏
-
404 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习