# 64 个单元测试红了一个,红的那条测的是纯数据逻辑:跨资源去重——保留一份文件、给记录打上标记 > 64 个单元测试红了一个,红的那条测的是纯数据逻辑:跨资源去重——保留一份文件、给记录打上标记。失败信息却既不是断言也不是崩溃,而是一段 StoreKit 的内部错误(SKServ - Canonical page: https://obelisk.club/blog/build-log-1465 - Author: Peter Zhang - Published: 2026-10-11 - Tags: build-log 64 个单元测试红了一个,红的那条测的是纯数据逻辑:跨资源去重——保留一份文件、给记录打上标记。失败信息却既不是断言也不是崩溃,而是一段 StoreKit 的内部错误(SKServiceErrorDomain Code=2)。这条测试从入口到出口都没碰过任何支付 API。 这种红为什么容易被误诊:错误文本出自测试宿主,不是被测代码。单元测试宿主启动的是整个 app,启动路径上初始化的每个子系统都会被每条测试无差别地继承;其中本地 StoreKit 服务在无头沙盒环境里跑不起来,它的报错就披着"测试失败"的皮冒出来。盯着测试名去修去重逻辑,第一眼方向就错了——错误域已经写明是谁坏的,只是没写它借了谁的名义。 通用的修法,顺序要紧: 1. 先读错误域,再读测试名。错误域指认故障方,测试名只指认受牵连方;两者对不上时,先怀疑环境,再怀疑代码。 2. 把测试不依赖的子系统从宿主启动路径里摘出去:测试环境守卫(检测到测试宿主就跳过初始化)、惰性初始化、或注入空实现。宿主越瘦,红得越准。 3. 真要测那个子系统,就给它自己的环境(测试 scheme 挂上 StoreKit configuration)和自己的测试层,别让它的环境问题一票否决整层数据完整性测试。 一分钟自检:挑一条最近"莫名其妙"红的测试,读它的错误域,然后问一句——这个域指向的子系统,从这条测试的代码路径真的可达吗?不可达,说明宿主启动得太多了;再顺手看一眼宿主 app 的启动路径,数一数有几个子系统在被每条测试无差别地拖起来。 这和一条老纪律是同一枚硬币的两面:绿色只证明被跑过的部分没问题,红色也可能只证明"有东西在这个环境里跑不起来"。两种情况都别只看计数(64 里红 1),要看那一个红到底在替谁说话。