知识卡片
测试专用API解决结构性耦合,让产品代码与测试代码独立演进
内容
解决[[测试是系统架构最外圈的组件脆弱测试问题会让系统变死板]]的具体做法之一,是为验证业务逻辑专门设计一个测试专用API——它拥有超级用户权限,允许测试代码绕开安全限制、跳过数据库这类成本高昂的资源,把系统直接强制设置到某种可测试的状态,本质上是用户界面所用的交互器和接口适配器的一个超集。设置这个API的目的不只是把测试和UI分开,更是要把测试代码的结构和应用程序其余部分的代码结构解耦。这里要防范的正是结构性耦合——测试代码里最强大也最阴险的一种耦合形式:如果测试套件给每个产品类配一个对应测试类、每个产品函数配一个对应测试函数,那这套测试就和应用程序在结构上紧紧绑死了,产品代码里任何函数或类的变更,都要求测试套件跟着做大量相应修改,这类测试极其脆弱、也会让产品代码变得死板。测试专用API的作用正是打破这种绑定:产品代码可以在不影响测试的前提下重构演进,测试代码也能在不影响生产代码的前提下重构演进——这种演进隔离之所以重要,是因为随着时间推移,测试代码天然会越来越具体详细,产品代码则天然会越来越抽象通用,两者的演进方向本就不同,结构性强耦合会严重阻碍甚至彻底堵死这个必需的分道演进过程。当然,这样一个拥有超级权限的API如果被部署进真正的生产系统会非常危险,因此测试专用API及其具体实现必须放进一个单独的、可独立部署的组件里,避免这份权限泄漏到生产环境。
参考来源
- 位置:《架构整洁之道》第28章《测试边界》"测试专用API""结构性耦合""安全性""本章小结"(源文件:_epub-src/text/part0014_split_013.html)
- 结论依据:原文定义测试专用API的超级权限用途及其解耦测试代码与应用代码结构的目的,说明结构性耦合(测试类与产品类一一对应)会随产品代码变更导致大量测试修改,并指出产品代码趋于抽象、测试代码趋于具体的不同演进方向需要被隔离,同时强调超级权限API必须放在独立部署组件里以防生产环境安全风险,直接支撑本卡片结论。
- 原始内容:设置测试API是为了将测试部分从应用程序中分离出来……结构性耦合是测试代码所具有的耦合关系中最强大、最阴险的一种形式……我们的产品代码则会趋向于越来越抽象和通用……应该将测试专用API及其对应的具体实现放置在一个单独的、可独立部署的组件中。