据认为不需要单元测试。 他们中只隐藏了一半事实。 而且只有在我们将其收集到集成测试中后,才会显示有关程序行为的真实信息。
这是有原因的,但是单元测试真的不完整吗,可以使其更可靠吗? 有多少原因导致其不完整?
假设我们有两个覆盖单元测试的组件,Caller和Callee。 调用方使用参数调用被调用方,并以某种方式使用返回的对象。 每个组件都有自己的一组依赖项,我们可以对其进行浸泡。
在集成过程中这些组件有哪些异常行为?
第一种情况是
两个组件都没有的
问题 。 例如,它们都取决于数据库的状态,授权,环境变量,全局变量,cookie,文件等。 判断这很简单,因为即使在非常大的程序中,此类争用点的数量也通常有限。
显然,可以通过减少依赖性的重新设计来解决该问题,
或者我们直接在顶级方案中模拟可能的错误,即,我们引入CallingStrategy组件(OffendingCaller,OffendedCallee){},并在CallingStrategy中模拟Callee崩溃和错误处理。 为此,不需要集成测试,但是需要了解其中一个组件的特定行为会对另一组件构成风险,并且最好将此场景隔离到一个组件中。
第二种情况:问题出在可集成对象的接口中,即
一个对象的不必要状态泄漏到另一个对象中 。
实际上,这是允许这样做的界面缺陷。 该问题的解决方案也非常明显-接口的键入和缩小,参数的早期验证。
正如我们所看到的,这两个原因都是非常普遍的,但是很清楚地指出没有其他原因会很高兴。
因此,如果我们检查类是否有1)内部状态和2)外部依赖关系,那么我们就没有理由怀疑单元测试的可靠性。
(在拐角处的某个地方,功能程序员正在用“我告诉过你”这样的词语悄悄地哭泣,但现在还没有。)
但是我们只能忘记或错过某种成瘾!
可以粗鲁地估计。 假设每个组件中有十个场景。 我们从十分之一中跳过一种情况。 例如,Callee突然返回null,而Caller突然收到NullPointerException。 我们需要犯两次错误,这意味着跌落到某处的概率为1/100。 很难想象这两个元素的集成方案会抓住这一点。 对于集成测试中的许多顺序调用的组件,捕获某些错误的可能性会增加,这意味着集成测试的堆栈越长,场景越多,证明它就越合理。
(累积误差的真正数学当然要复杂得多,但结果相差不大)。
但是,在执行集成测试的过程中,我们可以预期,由于依赖关系破裂而导致的噪声将大大增加,并且花费大量时间查找错误,并且它们也与堆栈的长度成正比。
也就是说,事实证明,
如果单元测试不好或缺失,则需要集成测试 。 例如,当在每个单元测试中仅检查有效脚本时,它们使用的接口太宽并且不分析常规依赖关系。