测试是贯穿整个研发周期,形成闭环,并持续改进。需求->开发->测试->交付->客户反馈->新需求
对软件测试的基本认知,可以促进我们达成共识,有了这个共识,就更容易进行下面的讨论。
基于对软件测试的这些认知,用一句话来说明软件测试的基本认知:基于对用户真实需求的理解,通过各种手段获得软件产品真实的、全方位的质量信息。无论是验证软件功能特性是否满足需求、评估产品的质量还是揭示产品的质量风险,都是基于获得的有关产品的真实的质量信息做出判断的,而缺陷可以看做是这个活动过程中的副产品。
可以看到:
在回答这三个基本问题的过程中,我们可以根据不同的场景、不同的维度、不同的测试方法、不同的技术和实践,抽取它们的共同点,先梳理下目前测试的维度
[名词解释] 冒烟测试(smoke test):是在软件开发过程中的一种针对软件版本包的快速基本功能验证策略,是对软件基本功能进行确认验证的手段,并非对软件版本包的深入测试。其主要目的是确认软件的基本功能正常,以便于进行后续的正式测试工作。冒烟测试现在多用于软件测试,但实际上,这一术语源自硬件行业。对一个硬件或硬件组件进行更改或修复后,直接给设备加电。如果电路板的设计或焊接有问题,比如哪里有短路,就会出现电路过热,冒烟甚至起火的情况。如果没有冒烟,则该组件就通过了测试。
[名词解释] 回归是指某个特性在特定事件(通常是代码修改)之后停止正常工作。术语回归和软件bug是同义词,可以互换使用。在实际的开发中,不免会碰到这样的问题:某个功能或模块在新版中从正常状态退化到了不正常的工作状态。出现了软件功能的退化。工程师应该在新版本上运行所有的测试用例(test case),以验证没有退化情况发生,这一过程就是回归测试。
测试是一个样本实验,需要精心分析和设计,努力以最小的代价并尽早地去揭示质量风险。基于上面的考虑,我们来正面回答下上面的三个问题:
也就是For Quality,from Quality objectives and by getting Quality data(为了质量而测,从质量目标出发、想方设法获取质量信息)。
测试业界的几个常见困惑:
测试覆盖率(test coverage)是衡量软件测试完整性的一个重要指标。掌握测试覆盖率数据,有利于客观认识软件质量,正常了解测试状态,有效改进测试工作。
如何度量测试覆盖率呢?在度量测试覆盖率之前,我们需要明确测试覆盖率的定义。毕竟,不同的定义会产生完全不同的覆盖率数据。
最著名的测试覆盖率就是代码覆盖率。这是一种面向软件开发和实现的定义。它关注的是在执行测试用例时,有哪些软件代码被执行了,有哪些软件代码没有被执行到。被执行的代码数量与代码总数据之间的比值,就是代码覆盖率。从代码粒度的维度来看,代码覆盖率可以进一步分为源文件覆盖率、类覆盖率、函数覆盖率、分支覆盖率、语句覆盖率等。
如何度量代码覆盖率呢?目前业界有现成的开源工具。目前主流的编程语言都有相关的工具。譬如Java语言有Jacoco,Go语言有GoCov,Python语言有Coverage.py。
上面这些度量工具一般只适用于白盒测试,尤其是单元测试。对于黑盒测试来说,度量代码覆盖率则相对困难多了。
主流编程语言一般都有现成的单元测试工具,按照既定的打开方式,拿来稍作配置即可使用。但是,如果想更进一步了解这些工具背后的实现原理,就需要花费一些功能了。
以Python覆盖率工具Coverage.py为例,它包括执行、分析和生成报告三大模块。最核心的执行模块依赖Python内置的trace函数。这是一个由Python解释器提供的,当每一行Python代码被执行时所激活的函数。基于trace函数,我们可以得到第一行被执行的代码所有的文件和行数。然后,结合软件源代码,我们就可以分析出测试的代码覆盖情况,最后生成覆盖报告。
对于黑盒测试来说,譬如系统测试、功能测试,测试用例通常是基于软件需求而不是软件实现所设计的。因此,度量这类测试完整性的手段一般是需求覆盖率,即测试所覆盖的需求数量与总需求数据的比值。视需求粒度的不同,需求覆盖率的具体表现也有不同。例如,系统测试针对的是比较粗的需求,而功能测试针对的是比较细的需求。
如何度量需求覆盖率呢?在DevOps没有普及之前,只能依赖人工计算,需要人工去标记每个测试用例和需求之间的映射关系。在云原生和DevOps不断往前推送的今天,已经有Ali的云效和腾讯的Tapd来产品化这些场景。
对于黑盒测试来说,由于测试是基于用户场景而不是软件实现设计的。因此,此时度量软件代码覆盖率,其意义并不显著,至少比不上需求覆盖率的。
代码覆盖率和需求覆盖率有一个共同点,即它们都是面向测试过程的指标。因此有个不足之处,即覆盖率数据可能无法完全反映真实的测试状态和水平。
对于代码覆盖率来说,一个让人困惑的问题是不是要做到100%:100%覆盖率不是目标。100%听起来肯定比95%要好,但是区别在于那些测试的价值对你可能是微不足道的。这要看哪种代码没有被测试覆盖,以及你的测试能否暴露程序的错误。100%的覆盖率并不能确保没有缺陷---它只能保证你所有的代码都执行了,不论程序的行为是否满足要求,因为代码的执行顺序和函数的参数值,都可能是千变万化的。与其追求代码覆盖率,不如将重点关注在确保写出有意义的测试。
对于需求覆盖率来说,100%的覆盖率也不能说“没有Bug”。因为需求可能有遗漏或存在缺陷,测试用例与需求之间的映射关系,尤其是用例是否真实能够覆盖对应的测试需求,也可能是存在疑问的。
测试的目的之一是发现软件缺陷。因此,衡量测试完整性的终极指标应该是面向测试结果的缺陷覆盖率或缺陷逃逸率,即测试所实际发现的缺陷数量与测试所应该发现的缺陷总量的比值。
软件测试一般是分为多个测试阶段的。每个阶段有每个阶段的任务。对于当前测试阶段来说,在后续阶段发现的缺陷中,属于当前阶段(而不是更早阶段)遗漏出去的缺陷是我们需要重点关注的。
虽然讨论缺陷覆盖率有一种“事后诸葛亮”的感觉,但是它的意义是不容忽视的。但缺陷覆盖率一方面提供了评价某一阶段测试工作成效的重要指标,另一方面为我们改进测试工作提供了重要参考。例如,针对每一个遗漏深入挖掘,举一反三,可以避免同类问题在未来再次发生。
上面介绍了三种常见的测试覆盖率的定义和度量方法,分别是代码覆盖率、需求覆盖率和缺陷覆盖率。它们适用于不同的场景,有各自的优势和不足。需要注意的是,它们解决了不同的问题,相互补充。
关于测试覆盖率,最重要的一点应该是迈出第一步,即有意识地去收集这种数据。没有覆盖率数据,测试工作会有点像“黑灯瞎火”中走路。有了覆盖率数据,并持续监测,利用和改进这个数据,才是一条让测试工作越来越好的光明大道。
[名词解释] 缺陷逃逸率,Defect Escape Percentage,简称DEP,是指软件产品发布后发现的缺陷数量与该软件产品在整个生命周期发现的所有缺陷数量的比率,通常用来衡量软件开发团队与测试团队对软件质量控制的水平。缺陷逃逸率的计算公式一般是:缺陷逃逸率(DEP)= [R2 / (R1 + R2)] * 100%其中:R1指的是产品发布前发现的缺陷数;R2是产品发布之后所发现的缺陷数
先对齐对软件测试的定义,在这个基础上再聊下对测试的认知,然后再聊下目前业界度量软件测试的办法。
认知,对事件本质的理解和把握。 认知是未来的常识。 认知有两个特性:时效性和相对性。 认知产生力量。正常的认知产生动力,错误的认知产生阻力。