本节摘要:交错着讲清区分单元层和集成层的决定因素——交互。集成测试的立足点在于"验证交互",因此它慢、贵、需要真实或高保真依赖,却也恰好能拦住单元层看不见的接缝缺陷。
一个"看起来像函数"的流程,一旦它真实地和数据库、消息队列或第三方服务打交道,我们就不再能靠 Mock 蒙混过关——因为这时候蒙混下来测的已经不是真相了。这就是集成测试的特质:它愿意接受慢、把控不了的代价,换取对真实交互的验证。它跟单元测试的分界线,不是"文件大不大",而是"要不要真东西参与"。
单元测试的一大优点,同时也是它的盲区:它隔离了外部世界。可真实的缺陷往往不在单件内部,而在"两个正常单件的接缝处"——正是单元层因为隔离而看不见的地方。集成测试就是专门去照那些暗角的灯。它能发现的问题主要有三类:接口不匹配(参数口径、返回结构、错误码)、数据不一致(字段类型、去重、约束、脏数据)、以及进程与协议层问题(超时、重试、消息体 schema)。这几类几乎每一种都足以让一个"单测全绿"的系统在线上翻车。
有人心疼集成测试的慢和贵,把它砍到几个冒烟用例。但值不值要看它拦的是哪种错——它拦的是"单测拦不了"的那类错,所以贵有贵的道理。深挖下去,它的价值还有三条容易被低估:
下面这张流程帮你在遇到接口时快速判断"这该归单元还是集成"。
背景:团队给支付对账写测试。若纯靠单元测试,对账逻辑很容易测——但那只证明"逻辑对",无法证明"接进真实对账文件的口径错没错"。于是他们保留了一条真实的集成用例:拿一份真实账单文件进来,走完整的外部结算服务接口,比对外部返回的字段。这条用例要跑四秒、依赖测试环境。
操作:把这条集成用例单独归到集成目录,只在 nightly 或 CI 的分层关卡里跑。结果:一次外部服务把"币种字段"从两位改成三位字符串时,单元测试全绿,只有这条集成用例红了,帮他们提前堵住一场线上对账事故。
解读:四秒钟的集成用例,拦下了单元层永不可见的接口口径漂移。变式:为了不拖慢日常提交,又可把这类用例再按"快集成/慢集成"两档拆分,快档进 PR 必跑,慢档进夜间。
集成测试的价值被三件"影响范围"的事限制着,超出也得打回。第一,它只对"被测接缝"负责,对"没定义契约的隐性依赖"无能为力——若两个模块靠共享一张表的隐含字段约定合作,即便写了集成用例,也往往测不到那个靠文档稀里糊涂维系的角落。第二,一次集成用例同时验证多个未知数时,产生的红灯难以定位,反而降低它的引导价值(这正是 3.2 为什么要谈"拼装顺序")。第三,一旦环境被共享缓存、外部时序污染,红绿灯会失真,把人引向"调测试"而不是"修产品"。
所以更稳的心法是:每条集成用例都尽量"一次只引入一个新变量"。铁律缺位下的"串一长串真依赖一起跑",看似更真,实则更难读、更难定位。宁可多跑几条聚焦的集成用例,也不要一条超大而全、红灯亮了半天定位不到接缝的巨无霸。
前面已经多次提到快慢分档,这里把具体的栏位说透。集成测试的价值建立在一个前提上:它要在"录入提交"和"准备上线"两条路的两端都设关卡,而不是退到只在夜间跑一次。一般建议设三道:
三道关卡分层的意义在于:红灯出现的时效和"要不要人立即响应"是两条轴。连 PR 都红的,立即响应;只在夜间黑的,排到第二天上午排查。真把这三道关卡装起来,人人才会把集成测试的绿灯当回事——毕竟它不再是一个"偶尔看一次"的角色。
有人觉得"反正有手工联调,集成测试可做可不做",这是另一处想当然。手工联调是"人对着一堆你能控制的接口点一遍",它既不自动、也难复跑,更关键的是它在注意力不集中时会漏掉没人点的角落;而集成测试是"把同一组接缝的验证写死、可重复运行"。两件事的目标重叠,但性质完全不同:手工联调适合没条件写自动化的临时探索,集成测试才是能长期守住的常态防线。
落到排布上,更稳的思路是"自动化的集成测试为主、手工联调为辅":凡是能写成可重复用例的接缝,都优先固化下来;手工联调只留给那些还飘着、没法定契约的新接缝。等新接缝稳定了,再把它从厨师嘴里挪进测试套件里。这样既能早发现,又不会让一摞手工清单替代掉真正的自动防线。
集成测试有它的主战场,但别把它当万能解药。它护得住的,是"两个零件连起来的约定";它护不住的,是"接口压根没定义、靠默契维系的隐性依赖",也护不住"没人写进接缝清单的角落"。真想靠它夯实质量,前提仍是先有清晰的接缝清单和契约——集成测试是放大器,不是无中生有的创造器。这提醒我们:先把"要夹哪个接缝、约定是什么"讲清楚,再谈上什么工具,顺序反了,加了再多的集成用例也补不回口径的缺失。