Back to Blog
·1 min read

一个构建全绿、单测全绿的 app,它的核心功能可能一次都没被执行过

一个构建全绿、单测全绿的 app,它的核心功能可能一次都没被执行过。 这不是假设。一个只做一件事的小工具——打开、输入、得到结果,整个 app 就为这条路径存在——直到有人问了一个

一个构建全绿、单测全绿的 app,它的核心功能可能一次都没被执行过。

这不是假设。一个只做一件事的小工具——打开、输入、得到结果,整个 app 就为这条路径存在——直到有人问了一个问题才发现:它的 UI 测试目录里从来没有一条用例真正驱动过这条路径。不是测试挂了,是这个测试从不存在。

为什么它能隐身这么久:缺一个测试,永远不会让构建变红。测试目标存在、周边用例通过,这两件事在任何报告里都和「核心路径已被覆盖」长得一模一样。缺席不产生信号,只有在场的东西才能失败。绿色证明的是零件都在转,不是这台机器能完成它存在的目的。

修法是有顺序的,而且顺序本身承重:

1. 先搭空壳:一条只启动 app、什么都不做的 UI 测试,先让它在模拟器上跑绿。这一步证明的是测试的管道是通的——否则后面第一次变红时,你分不清是产品错了还是测试环境错了。 2. 再填真实流程:启动 → 那个构成 app 存在理由的操作 → 断言一个用户真能观察到的结果。第一次红应该指向产品,而不是管道。 3. 最后把它钉进每次构建必跑的集合。覆盖是会蒸发的:一次重构、改个 target 名,它就能悄悄消失,而消失同样不产生任何信号。

一分钟自检:列出你 UI 测试类里的全部测试方法名,问一句——「如果 app 那件唯一的正事明天坏了,哪一条会变红?」答不出名字,你就是这个坑的下一位。

绿色构建回答的是「零件工作吗」,从不回答「产品工作吗」。这两个问题之间隔着的那条核心路径,得有人真的开过去一次,并且留下证据。

#build-log

Written by

Peter Zhang

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