Back to Blog
·1 min read

「测试没过」和「测试根本没跑」是两回事,但退出码看起来一模一样

「测试没过」和「测试根本没跑」是两回事,但退出码看起来一模一样。 给核心流程套 UI 测试护栏,总会遇到这么一天:命令红了,读输出才发现里面一条测试结果都没有——不是哪条用例挂了,

「测试没过」和「测试根本没跑」是两回事,但退出码看起来一模一样。

给核心流程套 UI 测试护栏,总会遇到这么一天:命令红了,读输出才发现里面一条测试结果都没有——不是哪条用例挂了,是测试 target 根本没编译过,编译错误就埋在构建日志中间,被测的流程一行都没执行到。

这类输出最容易被误读成三种之一:测试失败(其实产品代码没有任何证据)、测试通过(没有失败记录 ≠ 没有失败)、或者当成环境抖动直接重跑。正确的读法是承认第三种状态:无结论。这次运行对工作流没有任何发言权;先修测试 target 的编译错误,再谈流程对不对。

为什么它能长期隐形:xcodebuild 把「测试脚手架没建成」和「测试跑完且挂了」包在同一条命令、同一个非零退出码里。只看红绿的检查会把工具问题记成产品问题,或者反过来,于是下一个动作就花在了错误的层面——要么去调试一行从未执行过的产品代码,要么无限重跑一个必然复现的编译错误。

通用修法,顺序即关键:

1. 先判读「有没有判决」,再判读判决内容。标准就一条:输出里有没有 "Executed N tests" 这样的执行计数行。没有,或者为零,都是空判决——先去构建日志里找编译错误。 2. 把脚手架的编译错误当独立工作项修。此时不要顺手改产品代码:你手里还没有任何关于产品的证据。 3. 修完再跑。这一次的输出才值得读。

一分钟自检:跑一遍你的测试命令,grep 一下 "Executed"。计数缺失或为 0,你的红绿灯就都判给了空集——该修的是护栏本身,不是被护栏围住的东西。

老纪律的回响:绿灯只证明零件在转,不证明整机在走。执行计数就是那行把两者分开的证据。

#build-log

Written by

Peter Zhang

Building local-first Mac & iOS productivity apps at Obelisk Club.