TA的实践中我们有哪些困惑?
我们看到,TA不仅提升了软件测试的生产力,而且改进了软件工程中的生产关系(对开发和CI等带来了积极变化)。那么,有什么理由不去推广TA呢?是的,在软件测试界,TA受到了重视。虽然很多测试人员未必能全面了解TA的诸多好处,但其实现TA的愿望普遍是强烈的。我们看到,在许多软件项目中,TA已经或正在被实践着。但是,实践的效果如何?TA是否给个人、部门、公司带来了期望中的收益?据了解,很多时候答案是否定的。在TA上投入不低,但是似乎收效不高。对TA产生质疑、甚至摒弃的声音也部分存在。那么,对于TA,人们到底有哪些困惑呢?
TA收益之惑
一切软件测试工作都是为发现软件问题、提升软件质量而存在的,TA也不例外。对于TA的收益,一个最直接的衡量指标就是通过自动化测试所发现的软件问题的数量。如果(1)TA无法有效地发现问题,或者(2)TA发现了很多问题,但是经过分析,这些问题许多都不是软件问题,而是其他类型的问题,那么TA的收益就会低。不仅开发人员,甚至测试人员自身都会对TA形成负面评价。以笔者负责过的公司某款产品的自动化测试为例。一共5条测试线(Test Line),分别对应5种不同的产品配置。每条测试线运行相同功能的19个TA Case。每条测试线在每晚定时从CI系统获取一个或多个当天的软件包,升级测试环境,然后重复执行10次回归测试。笔者每天的工作是对前一天晚上执行的50次测试结果进行分析,发现问题,对问题进行跟踪处理,并撰写测试报告。为期3个月,总共测试了160多个软件包,执行了4000余次回归。经过对87份测试日报(Daily Report)和14份周报(Weekly Report)的统计分析,三个月内,一共发现了99个问题,其中有25个是软件问题,57个是测试线问题,还有17个问题无法归类。我们可以看到:
-
发现的测试线问题太多,占比接近60%。所谓测试线问题,就是测试自身的问题。 测试自身问题的来源五花八门,包括测试Case本身、测试Case调用的底层TA库、测试环境中的外部模块(第三方硬件、网络设备、操作系统)、各种人为的误操作等等。为了发现被测软件的问题、检验被测软件的质量,我们投入许多人力物力,来搭建自动化的测试系统。结果事与愿违,我们发现的问题竟然大多数是测试系统自身的问题。这完全是本末倒置,无法让人接受。
- 尽管发现了25个软件问题,但问题的分析和跟踪并不彻底。5条测试线持续运行3个月,值得欣慰的收获就是发现了25个软件问题。但是,对于测试人员来说,仅仅发现问题是远远不够的。我们还需要对问题的现象和原因进行深入分析,对问题的状态进行紧密跟踪,从而举一反三。但是,由于我们发现了太多的非软件问题,仅仅分析和解决这些非软件问题就要花费测试人员大量的时间和精力。总的资源受限,投入到非软件问题上的资源越多,投入到软件问题上的资源就越少。事实上,虽然发现了25个软件问题,但真正有效的软件问题并没有25个。一些软件问题并没有得到深入地分析。在一段时间内没有复现,便被关闭(Close)了。事实上,软件的隐患或许并没有根除,问题仍然有可能在未来的某个时候再次出现。另外,那17个无法归类的问题也多数属于这种类型,问题的根源对于测试人员来说是未知的。
TA维护之痛
TA本质上是一种软件活动(Software Activity)。任何一项软件活动都离不开维护(Maintenance)。通常来说,维护是一种创造的实际价值非常有限,但却要消耗一定资源的事情。维护成本的高低,直接决定于软件工作的质量。TA的维护成本过高,可能体现在多个方面:
- TA测试环境的维护成本过高。相比手动测试环境,TA测试环境通常要更加复杂一些。TA是用测试软件去验证被测软件。因此我们至少需要增加一个设备(或占用一个已有设备的部分空间)来运行测试软件。通常,
TA测试环境的维护成本,与测试环境的复杂度成正比。
如果TA测试环境过于复杂,那么其维护成本一定不会低。测试环境中任何一个设备不稳定,都会造成整个测试环境的不稳定。自动化的隐含意义就是”无人值守”,而”无人值守”意味着易受外界干扰。系统越复杂,抗外界干扰能力就越差。如果设计TA系统时,没有在满足测试目标的前提下,尽可能地简化设计,那么就会导致TA系统过于复杂,TA的后期维护成本也就过高。
-
TA Case的维护成本过高。TA Case本质上就是代码。TA Case能不能工作(Work),决定了测试的目的能不能达到。但是,TA Case仅仅能够工作是远远不够的,我们要对TA Case的质量提出要求。因为TA Case的质量直接决定TA Case后期的维护成本。通常来说,测试人员普遍缺乏编程经验,试图一下子就写出高质量TA Case的可能性是很低的。编程经验不足的人,很容易写出(1) 大段大段的重复代码 (2)互相依赖、结构混乱的代码块。软件开发中”Don’t Repeat Your Self”和”高内聚,低耦合”等众所周知的准则,无时无刻不被TA Case实现人员违反着。在软件工程中,有一个未必精确但却引起广泛共鸣的说法:
软件代码Bug的数量与代码长度的平方成正比,即 $Error = More\ Code ^2$。
通过简单拷贝、模仿所堆积起来的TA Case,不仅功能不稳定,自身容易出现各种Bug,而且后期也是很难维护的。我曾经对某位同事的一份TA Case文件进行了重构。统计了一些简单的指标,对重构前和重构后的情况进行对比,如下表所示:
量化指标 重构前 重构后 测试用例文件总行数 238 126 单行最大字符个数(不包括空格/Tab) 343 132 单个函数的最大长度(行) 18 8 单个函数的最大参数个数 9 4 单个常量出现的最大次数 9 1 导入的外部库 9 1 封装的通用(Common)库函数 0 12 重构带来了什么变化?举例来说,如果某个常量的值变了,原本我们需要寻找并修改9处,而现在只需要修改1处;原本我们没有封装任何通用的库函数,现在我们封装了12个可供其他Case调用的函数,而这有可能会(事实证明确实)大大减少其他Case的代码长度。试想,如果没有这次重构,后果会怎样?如果一个系统,数以百计的TA Case,都是类似上面这种重构前的状态,后期我们如何维护?对于软件来说,变化是常态。无论是软件需求的变化,还是软件实现的重构,抑或软件Bug的修复,都有可能需要TA Case去做适配和修改。如果每一次外部变动,都导致TA Case失败一大片,而且需要花费很大的成本才能修复失败的TA Case,那TA Case维护成本之高将让所有人都难以承受。
- TA支撑库的维护成本过高。一个完整的测试软件通常包含(1)TA Case (2)TA Library。TA Library,是由TA Case直接调用,并与被测软件实际交互的模块。本质上,所有自动化的工作是由TA Library来完成的,其质量至关重要。TA Library不稳定,将会对所有使用这个Library的TA Case的稳定性产生影响。站在维护的角度,TA Library自身的维护成本会在TA Case那里得到成倍的放大。一个精简的Library,总是比一个复杂的Library稳定可靠。TA Library应当在满足TA Case需求的前提下,做得尽可能简单。没有前期的高质量,就没有后期的低维护。我们意图用测试软件去测被测软件,那么“打铁还需自身硬”,测试软件自身的质量应该足够高。作为测试软件的核心模块,TA Library的质量更是重中之重。许多TA Library自身并没有经过严格的测试,事实上是很难承担起测试产品软件重任的。另外,对于任何软件来说,出现Bug并不可怕,可怕的是对Bug的响应时间太慢。TA Library的维护成本,部分地体现在TA Library对自身Bug的处理效率上,而这直接影响整个自动化测试工作的进度。从实际经验看,如果TA Library的Bug修复时间不是以小时(Hour)计,而是以天(Day)来计,那么使用者的体验就会很差,TA的效益也就大打折扣。
我是肖哥shelwin,一个高质量软件工程实践者和推动者。欢迎扫描下方二维码,添加我的个人公众号测试不将就,获得更多自动化测试, 持续集成, 软件工程实践, Python编程等领域原创文章。