什么是可测试性
可测试性的原则
测试软件理论上很简单:只要强迫程序在正确数据、错误数据、没有数据或不完整数据的情况下工作,验证结果是否满足预期。你如何强迫程序使用你的输入数据?你如何衡量结果的正确性?如果失败了,你如何跟踪失败的模块?
这些问题都是“为可测试性而设计”(DfT)范式的基础。DfT定义了3个属性,任何软件单元必须满足它们才会容易测试。
- 控制性:控制性是指测试者在多大程度上可以给正在测试的软件提供固定的输入数据。任何软件都应该清楚地表明需要什么参数以及生成什么返回值。此外,任何软件都应该抽象它的依赖(参数和低级模块),并为外部调用者提供随意注入的方式。
- 可见性:可见性是指观察正在测试的软件的当前状态以及它所产生的任何输出的能力。可见性都是关于在方法执行后验证后置条件的事情。
- 简约性:简单和极其内聚的组件非常适合测试,因为你需要测试的越少,你就能做得越可靠、快速。
一般而言,简约性对于任何系统在任何情况下都是一个正面的属性。测试毫无疑问也不例外。
可测试性为什么值得拥有
可测试性比具体的测试步骤更重要。可测试性是软件的一个特性,代表着质量的(好)评价。测试是一个流程,目的是验证代码是否满足预期。
成功应用DfT的话,你的代码通常会有很高的质量,有助于维护和重构,也更易被碰到它的开发者理解。在这种情况下,写单元测试非常有效,总的来说也更加容易。
可测试性的ROI
可测试性的投资回报(Return on Investment,ROI)就是你的代码质量得到改善。在写类的时候,要以使它们变得可测试为目标,这样会促使你喜欢简洁,每次迈进一小步。你很快就会发现某个类什么时候变得臃肿,找到你需要注入依赖的地方,识别出你需要处理的实际依赖。
你当然可以只写可测试代码,但不为每个类和组件写所需的那些测试。但测试和类一起写有助于你理解这个ROI。
但是,最终的目标是写出好代码,而不是好测试。
如果你需要证明可测试性的ROI给你自己或者你的经理看,我们建议你实验一下类和测试一起写。这可以证明产生的测试是一个回归工具,并证明你的代码能在任何测试过的条件下(包括常见情况和边界情况)工作。这个测试也改善了类的整体设计,因为要写测试,你最终会使类的公共接口变得更易使用。测试意味着有更多代码编写和维护,这是额外的代价。
即便这样,可测试性其实是某种个人顿悟,每个开发者和开发团队最终都会经历,但只有到合适的时机才会出现。