2.3 软件可测试性
2.3.1 可测试性生命周期过程模型
可测试性(Testability)是指软件系统或组件或程序片段的属性能够被验证的程度,即一个软件系统能够被测试的难易程度或被确认的能力。理论上,对于任何一个软件,总能找到办法对其进行测试验证,但只有那些具有良好可测试性的软件,才可能得到高效、完备的测试。一个函数如果粒度太大,多功能带来多入参问题,必然产生多组合验证等问题,显著增加测试初始化难度及测试生命周期成本。微服务架构下,如果构建Mock服务的难度和成本过高,会直接造成不可测或测试成本过高等。
基于云原生等技术,软件系统的规模及复杂性与日俱增,如果被测系统缺乏良好的可测试性,软件测试将愈发困难,传统软件测试方法亦将受到前所未有的挑战。软件开发,为测试而设计、为部署而设计、为监控而设计、为扩展而设计、为失效而设计。这是认识和理念的根本转变。良好的可测试性让软件缺陷无处遁形,有利于软件测试工作有效开展,有利于降低质量风险和测试成本。
软件可测试性包括需求、架构、设计、代码、数据等的可测试性。基于设计方法学的软件设计,基于编码规则的编码实现,是保证可测试性的基础,简化软件设计和编码,是改进可测试性的重要手段。软件可测试性生命周期过程模型如图2-9所示。
图2-9 软件可测试性生命周期过程模型
可测试性是软件的通用质量特性之一,与开发同策划、同设计、同验证、同改进。需求分析阶段,在业务层面对每个用户故事建立验收标准,在功能层面基于用户要求,确定测试性需求;软件设计阶段,从架构设计、接口设计、日志设计等,建立可测试性规范,采用良好的设计模式,遵守高内聚低耦合、面向对象的SOLID等设计原则,为测试提供额外的接口;编码实现阶段,为可测试性设计代码规范,确保代码具有良好的可测试性。
例如,避免在构造函数中引入业务逻辑,如实例化和初始化协作对象、调用静态方法及复杂赋值逻辑等。在一个类中,只传入所需对象作为参数,避免在传入对象中进一步挖掘依赖对象。图2-10所示反例和正例,清晰地说明了软件的可测试性问题。
图2-10 一个软件可测试性的反例和正例