软件测试认知小结

2023-03-07 13:56:04 浏览数 (2)

软件测试认知小结软件测试的基本认知软件测试的灵魂三问如何度量软件测试工作的质量--覆盖率小结

测试是贯穿整个研发周期,形成闭环,并持续改进。需求->开发->测试->交付->客户反馈->新需求

软件测试的基本认知

对软件测试的基本认知,可以促进我们达成共识,有了这个共识,就更容易进行下面的讨论。

  • 软件测试是验证软件功能特性是否满足需求;
  • 软件测试就是发现软件中存在的缺陷
  • 软件测试包含了静态测试-- 需求、设计、代码的评审活动
  • 软件测试是系统、完整地评估软件产品质量,提供质量信息
  • 软件测试是暴露、揭示产品质量风险
  • 软件测试不仅是技术性活动,而且是社会性、心理等多方面的综合性活动。
  • 软件测试是通过投入质量保障性成本来极大地减少劣质成本

基于对软件测试的这些认知,用一句话来说明软件测试的基本认知:基于对用户真实需求的理解,通过各种手段获得软件产品真实的、全方位的质量信息。无论是验证软件功能特性是否满足需求、评估产品的质量还是揭示产品的质量风险,都是基于获得的有关产品的真实的质量信息做出判断的,而缺陷可以看做是这个活动过程中的副产品。

可以看到:

  • 强调的是用户的真实需求,而不是虚假的、错误的需求,业务的需求最终要分解成用户角色的需求,而系统的功能/非功能性需求也是为了满足用户的需求。
  • 强调对用户真实需求的理解,一方面体现“没有用户就没有质量,质量相对用户而存在”,我们必须从用户角度出发来完成测试。
  • “软件产品”不局限于程序,还包括数据、需求文档、设计文档、代码、用户手册、技术手册等。
软件测试的灵魂三问
  1. 为什么要测?
  2. 测什么?
  3. 如何测?

在回答这三个基本问题的过程中,我们可以根据不同的场景、不同的维度、不同的测试方法、不同的技术和实践,抽取它们的共同点,先梳理下目前测试的维度

  • 根据测试对象不同不同,可以分为
    1. Windows/MacOS/Linux native应用
    2. Web应用
    3. 移动端App。还可以细分为Android,IOS,HarmonyOS
    4. 嵌入式软件
  • 根据不同的测试目标,可以分为
    1. 功能测试(Function Testing)
    2. 边界分析测试
    3. 性能测试(Performance Testing)
    4. 安全性测试
    5. 兼容性测试
    6. 渗透测试(Penetration Testing)
    7. 回归测试(Stress Testing)
    8. 破坏性测试(Failure Testing)
  • 根据不同的测试粒度或层次
    1. 单元测试(Unit Testing),属于白盒测试(White Box Testing )
    2. 接口测试(API Testing),属于黑盒测试(Black Box Testing)
    3. 集成测试(Integration Testing),属于黑盒测试
    4. 回归测试(Regression Testing),属于黑盒测试
    5. 系统测试(System Testing),属于黑盒测试
    6. 冒烟测试(Smoke Testing),属于黑盒测试
    7. 验收测试(Acceptance Testing) ,属于黑盒测试
  • 不同的团队和不同的产品
    1. 工具线测试 【根据团队】
    2. 业务线测试 【根据团队】
    3. 网易音乐测试 【根据产品】
    4. 有道笔记测试【根据产品】

[名词解释] 冒烟测试(smoke test):是在软件开发过程中的一种针对软件版本包的快速基本功能验证策略,是对软件基本功能进行确认验证的手段,并非对软件版本包的深入测试。其主要目的是确认软件的基本功能正常,以便于进行后续的正式测试工作。冒烟测试现在多用于软件测试,但实际上,这一术语源自硬件行业。对一个硬件或硬件组件进行更改或修复后,直接给设备加电。如果电路板的设计或焊接有问题,比如哪里有短路,就会出现电路过热,冒烟甚至起火的情况。如果没有冒烟,则该组件就通过了测试。

[名词解释] 回归是指某个特性在特定事件(通常是代码修改)之后停止正常工作。术语回归和软件bug是同义词,可以互换使用。在实际的开发中,不免会碰到这样的问题:某个功能或模块在新版中从正常状态退化到了不正常的工作状态。出现了软件功能的退化。工程师应该在新版本上运行所有的测试用例(test case),以验证没有退化情况发生,这一过程就是回归测试。

测试是一个样本实验,需要精心分析和设计,努力以最小的代价并尽早地去揭示质量风险。基于上面的考虑,我们来正面回答下上面的三个问题:

  • 为什么测?只要是人做的工作,就不能保证万无一失,会存在问题。如果软件带着问题出去,就很有可能给客户带来损失或让客户不满意,最终会导致企业的利益受损。过去无数的质量事故,最终导致企业的利益受损。过去无数的质量事故,也证明了这一点,在交付给客户之前,软件需要得到充分的测试,否则后续的修复成本就很高,后果严重。
  • 测什么?取决于交付的质量目标,即从质量目标出发,以终为始,进行目标分解,然后针对每一个特定的子目标来确定要获得的有关被测对象的质量数据,从而确定其测试范围或测试项。如果再进一步,我们根据用户对质量特性、功能特性的感受不同来决定测试项的优先级。这部分属于测试分析的工作,并涉及测试风险和测试策略。
  • 如何测?就是找到获取被测对象的质量数据的方式、方法或手段,包括测试方案设计、场景设计、测试用例或测试数据等的设计。

也就是For Quality,from Quality objectives and by getting Quality data(为了质量而测,从质量目标出发、想方设法获取质量信息)。

测试业界的几个常见困惑:

  • 为什么这个Bug测不出来?
  1. 测试是不能穷尽的,测试总是有风险的,而且开发写出的Bug越多,测试漏掉的Bug越多;
  2. 测试只能证明已发现的缺陷是缺陷,不能证明软件没有缺陷,因为测试是一个样本实验。
  • 测试怎么测的?到底会不会测?对所做的测试工作(包括测试目标的制定、测试分析的过程以及对应的测试设计方法)能解释清楚,而且测试不能孤立的工作,受需求(如需求模糊)、系统设计(如耦合性、复杂性)、编程(如偷偷修改代码)等影响,测试要与产品、开发等紧密合作。
  • 测试快点啊!为什么总是测试拖后腿,最后才报Bug?我们可以在开发写完代码之前完成测试分析、测试计划和测试设计,但系统层次的测试执行需要等待开发完成、版本构建完成,测试执行是后期工作,测试时间容易被开发前期工作挤掉一部分,项目的延期容易造成错觉--测试拖后腿。
如何度量软件测试工作的质量--覆盖率

  • 代码覆盖率
  • 需求覆盖率
  • 缺陷覆盖率

测试覆盖率(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是产品发布之后所发现的缺陷数

小结

先对齐对软件测试的定义,在这个基础上再聊下对测试的认知,然后再聊下目前业界度量软件测试的办法。

认知,对事件本质的理解和把握。 认知是未来的常识。 认知有两个特性:时效性和相对性。 认知产生力量。正常的认知产生动力,错误的认知产生阻力。

0 人点赞