1.3.2 可测试性差引发的问题
很多觉得可测试性是个新命题,在软件测试发展的很长一段时间里,这个概念似乎并没有被广泛提及。那是因为以前的软件测试是偏粗放式的黑盒模式,而且测试团队和开发团队分离,测试工程师往往到了研发后期才会介入,测试始终处于被动接受的状态,并且大量的测试与验证都偏向黑盒功能,所以可测试性的矛盾并没有显现出来。但是现在,随着测试左移、开发者自测、测试与开发融合以及精准测试的广泛普及,粗放式的黑盒模式已经无法满足软件的质量要求。
如果继续忽视可测试性,不从源头上对可测试性予以重视,将会导致研发过程中系统不可测或测试成本过高的窘境。可以说,忽视可测试性就是在累积技术债务。更何况,今天大行其道的DevOps全程都离不开测试,测试成了拉通持续集成/持续交付(Continuous Integration/Continuous Delivery,CI/CD)各个阶段的连接器,如果可测试性不佳,整个CI/CD的效率就会大受影响。
为了帮助大家更好地理解可测试性,下面列举一些实际的可测试性问题。
1. GUI测试层面
● 登录场景下的图片验证码:图片验证码虽然不影响手工测试,但是会影响自动化测试的可测试性,用OCR(Optical Character Recognition,光学字符识别)技术识别图片验证码往往不够稳定,如果能够实现稳定识别,反而说明验证码机制有问题。如果登录实现不了自动化,就会影响很多其他的自动化测试场景。登录过程中的短信验证码也有类似的可测试性问题。
● 页面控件没有统一且稳定的ID标识:如果页面控件没有统一且稳定(不随版本发布而变化)的ID标识,自动化测试脚本中控件识别的稳定性就会大打折扣。虽然测试脚本可以通过组合属性、模糊识别等技术手段来提升识别的稳定性,但是测试的成本会变高。
● 非标准控件的识别:非标准的前端页面控件等无法通过GUI自动化测试识别出来。
● 需要对图片形式的输出进行验证:图片的验证缺乏有效的工具来支持。
2. 接口测试层面
● 接口测试缺乏详细的设计文档:接口测试如果没有设计契约文档作为衡量测试结果的依据,就会造成测试沟通成本高昂,陷入无法有效开展测试结果验证、开发人员和测试人员相互推诿的窘境。
● 构建Mock服务的难度和成本过高:在微服务架构下,如果构建Mock服务的难度和成本过高,就会直接造成接口不可测或者测试成本过高。
● 接口调用的结果验证困难:接口成功调用后,判断接口行为是否符合预期的验证点难以获取。
● 接口调用不具有幂等性:接口内部处理逻辑依赖于未决因素(如时间、不可控输入、随机变量等)破坏接口调用的幂等性。
3. 代码测试层面
● 私有函数的调用:在代码测试中,私有函数无法直接调用。
● 私有变量的访问:私有变量缺乏访问手段,以至于无法进行结果验证。
● 代码依赖关系复杂:被测代码中依赖了外部系统或者不可控组件,比如依赖第三方服务、网络通信、数据库等。
● 代码可读性差:代码采用了“奇技淫巧”,造成可读性差,同时缺乏必要的注释说明。
● 代码的圈复杂度过高:圈复杂度过高的代码往往很难设计测试。
4. 通用测试层面
● 无法获取软件内部信息:测试执行过程中,有些结果的验证需要获取软件内部信息进行比对,如果无法通过低成本的手段获取软件内部信息,测试的验证成本就会很高。
● 多样性的测试数据的构建:很多测试设计都依赖于特定的测试数据,如果多样性的测试数据的构建比较困难,也会直接影响系统的可测试性。
● 无法获取系统运行时的实时配置:无法获取系统运行时的实时配置意味着无法重建测试环境进行问题的重现和定位,从而增加了测试的难度与不确定性。
● 压测场景下的性能剖析:很多性能问题只有在高负载场景下才能重现,但是在高负载场景下,无法通过日志的方式来获取系统性能数据,因为一旦提高了日志等级,日志输出就会成为系统瓶颈,进而把原来的性能问题掩盖掉。
由此可见,可测试性问题不仅出现在端到端的功能测试层面,还出现在接口测试和代码测试层面。可测试性对于自动化测试的实现成本也很关键。