00 引言
1. 三个层次聊测试体系
测试人员缺乏体系化思维?新建产品团队或者新启项目,如何搭建质量保障体系?
大家都接触过不计其数的测试、质量方面的文章或者培训课程,内容不乏测试实践、技术相关,但是却很难构建自己的测试体系。基于很多朋友类似的困惑,结合本人多年的团队实践和咨询经验,从基础、进阶和高级三个不同的层次来跟大家探讨测试体系化思维的构建。
《构建测试的体系化思维(进阶篇)》(本文)
《构建测试的体系化思维(高级篇)》(待发布)
2. 基础篇内容回顾
2022 年 1 月份发布了 《构建测试的体系化思维(基础篇)》(后文简称《基础篇》),从测试的五个基本职责出发,围绕这五个基本职责介绍了相应的实践活动和方法集。
理解和澄清业务需求
制定策略并设计测试
实现和执行测试
缺陷管理与分析
质量反馈与风险识别
3. 进阶篇内容概要
本文为进阶篇,将跳出测试,从软件质量的角度来看体系化思维的构建。
1)从测试到质量:跳出测试,从质量维度来看测试的体系化建设。
2)质量保障与质量内建:质量是产品与生俱来的,质量内建才是保障质量的根本。
3)质量内建深入实践:质量内建如何落地是大家最为关注的问题,深入质量内建实践介绍,供大家落地实践参考。
01 从测试到质量
1. 为什么要从测试转变到质量
在 《基础篇》中提到的五个测试基本职责,那是测试人员开展测试工作务必了解的方方面面,是做好测试工作的基础。
但是,要做好软件产品的质量保障工作,光从做好测试的角度考虑是远远不够的,原因主要有两个方面:
软件质量不能通过测试来提高。著名质量管理专家戴明提到:“质量没法检测出来,软件产品开发出来后质量就已经在那了。”
软件测试可以验证软件质量是否满足需求,但是随着软件生态的复杂性和不确定性增加,没有办法预知软件行为,也就没法通过测试来验证软件质量的方方面面。
因此,测试是基本功,但只关注测试是不够的。需要跳出测试,将视野调整到软件开发全生命周期质量的角度,关注质量的各个维度,才能更好地建立体系化思维,才能更好地做好软件产品的质量保障工作。
在阅读后面内容之前,我希望读者朋友们先花 10 秒钟思考以下问题:
- 问题:跳出测试,从软件质量的角度思考,我们需要关注哪些方面?
这是一个老生常谈的问题,答案似乎大家也都很清楚,但现实中又是很容易被忽视、被误解的问题。
2. 软件质量的定义
在回答上面问题之前,我们先来看看维基百科对软件质量的定义 ( https://en.wikipedia.org/wiki/Software_quality )。如下图所示:
维基百科对软件质量的定义包括两个方面:
软件功能质量:基于功能需求规范看软件是否提供了相应的功能,这是用户使用软件的角度,是软件外部的质量。
软件结构质量:对支持功能需求交付的非功能需求的满足情况,比如健壮性、可维护性等,这是从软件内部结构来看,是软件内部的质量。
维基百科的这个定义跟咱平常提到的软件质量包含外部质量和内部质量是一致的。外部质量是从软件外部可感知的,是从用户角度对软件感知到的使用质量;内部质量则涉及到软件的内部形态,包括技术架构和代码质量等,是从团队开发人员的角度感知到的。
相信大家对于外部质量好理解,是用户角度能够感知到的质量。而内部质量往往很容易被忽视,其实这也是因为人们普遍容易追求短期利益,看不到内部质量给软件产品带来的长远影响,这里想给大家看个非常熟悉的图,以增强对内部质量的重视。
不加整理的富含技术债的代码,就如同图中杂乱无章缠绕在一起的电线,严重影响着产品缺陷定位修复、后期功能扩展等。
3. 容易忽视的质量影响因素
理解了质量的定义,在日常软件开发工作中有哪些因素是会影响到软件质量的呢?其实,影响因素特别多,可能包括但不限于以下这些:
1)需求分析过程仓促,或者参与人员角色比较单一,导致业务上下文了解不够,关键场景缺乏考虑等;
2)忙于交付更多的特性,忽略了对代码质量的关注,该重构的没有重构,在原本不太健康的代码基础上继续增加更多的代码,导致混乱,筑起高高的技术债;
3)没有足够的测试覆盖,导致新增代码容易破坏已有功能;
4)开发人员提交代码后,就投入新代码的开发,对所提交代码缺乏关注,持续集成流水线上测试挂了不能及时修复,可能影响后面的测试进度;
5)大面积的重构发生在发布前夕,无法全面回归,带来很大的风险;
6)项目初期只考虑少量用户的场景,随着业务的发展,系统功能难以扩展,导致严重性能瓶颈;
7)技术选型失误,开发困难,没有及时改进,一错再错,最后问题严重到无法弥补;
8)第三方组件评估不够充分,导致线上环境无法承载等;
9)开发缺少对异常情况的处理,测试过程缺乏探索,只覆盖到主干路径,边角用例可能引发问题;
10)开发或者测试都只考虑当前功能模块,缺乏更广范围的考虑;
11)缺乏跨功能需求的关注,导致严重的安全或者性能问题;
12)对线上环境了解不够,而且没有足够日志信息记录,线上问题难以定位,导致宕机时间过长;
13)等更多……
02 质量保障与质量内建
1. 质量如何保障
从质量维度来看体系化思维的构建,而质量是产品与生俱来的,做好软件产品的质量保障工作更为有效的方式就是要将质量构建到软件产品本身,提高软件产品与生俱来的质量。这也就是质量内建(Build Quality In)的概念。
这个还是太抽象,为了更清楚地解释质量内建,先来看两个概念:暴露缺陷与预防缺陷。
2. 暴露缺陷与预防缺陷
“暴露缺陷”的概念众所周知,就是软件所暴露出来的缺陷,通常在测试或使用过程中被发现。
如果能够全面统计一个软件产品的所有可能引起缺陷的地方,我们可以说该软件存在缺陷的总量是一定的。当然,现实情况是我们不可能全面考虑到所有因素,缺陷是很难穷尽的。
如果这一定数量的缺陷中有一部分可以通过某些措施来预防,那么软件在测试或最终用户使用过程中所暴露出来的缺陷数量就会减少,这就是缺陷预防——减少暴露给用户的缺陷。
软件开发过程是个持续递增的过程,预防缺陷也不是一蹴而就的事情,需要在整个软件开发过程持续地进行。当然,尽早预防缺陷会更好,这样可以显著减少缺陷修复的成本,提高投入产出比。下图曲线非常清晰地展示了修复不同阶段暴露出来的缺陷所需成本的差异,修复成本是随着软件开发周期显著增加的。
3. 质量内建如何做
将缺陷概念扩展为软件产品质量相关的所有问题,那么做好了缺陷预防也就是做到了质量内建。
前文提到过容易被忽视的质量影响因素,要做好质量内建这些因素都是需要重点关注的。
但是,由于软件开发过程的复杂性,要一次性做对所有事情、预防所有的缺陷是不可能的。因此,质量内建并不是严格意义上的不能有任何缺陷暴露,而是需要在软件开发生命周期中尽早地把事情做对,并且通过持续的获取快速的反馈来纠偏。
我们都知道那个有名的 PDCA 环(也称“戴明环”):
将质量管理分为四个阶段,即 Plan(计划)、Do(执行)、Check(检查) 和 Act(处理)。在质量管理活动中,要求把各项工作按照作出计划、计划实施、检查实施效果,然后将成功的纳入标准,不成功的留待下一循环去解决。
质量内建可以理解为在软件开发全生命周期中,从需求到线上频繁地执行 PDCA 环,小步前进,持续反馈验证,及时调整改进。如下图所示:
03 质量内建深入实践
前面主要从概念和理念层面介绍了质量和质量内建,这些内容对构建体系化思维是至关重要的,有助于拓宽视野,形成全局观。但光有这些内容不够,还得了解具体的落地实施方法。接下来就从质量内建相关实践来探讨质量内建在软件开发生命周期的落地实施方案。
1. 质量内建的核心
在介绍具体的质量内建实践之前,还是需要从抽象层面来理解质量内建的核心,其内容可以分为四个方面:
测试左移
快速反馈
测试右移
全员参与
1.1 测试左移
传统软件开发会分成分析、设计、开发、测试、发布等几个相对独立的阶段,而测试是其中发生在开发完成之后的一个阶段。
测试左移是针对传统这种独立测试阶段来说的,不再强调独立的测试阶段,而是要将测试活动左移到软件开发生命周期的最早阶段(最左边)——需求阶段,从需求阶段开始做好缺陷预防工作。
要特别提醒注意的是,测试左移不是测试人员左移,而是强调测试活动左移:
左移到传统独立测试阶段左侧就叫左移,不一定是左移到需求阶段。当然,根据前面对质量内建的阐述,理想情况下肯定是越左越好。如果做不到彻底左移,能移一步也是进步。
测试人员的确需要左移参与相应的活动。但是,如果测试人员参与需求阶段,却没有起到澄清需求、验证需求有效性的作用,那就不是有效的测试左移,关键要看成效。
不仅测试人员要左移,开发等其他角色也需要左移。因为需求有效性的验证,需要不同角色的经验,需要来自不同视角的输入;不同角色都有责任参与到每个环节的测试活动中来。
只要能做到从需求阶段开始就有相应的测试活动,不一定都是测试人员参与。这里强调的是测试活动要有,哪个角色来做不是最关键的,角色其实就是戴了一顶帽子而已。我们知道,有的团队是没有测试人员的,但不代表这些团队没有测试活动。
1.2 快速反馈
快速反馈,也就是频繁持续地反馈,可以理解为一个持续测试的过程。
通常快速反馈需要有自动化的支撑,比如自动化测试、流水线上自动代码扫描等;也可以是一些人工参与的实践环节,比如手动测试、各类评审和验收等。通过这样的一些实践活动尽快地获取相应工作(可能是需求分析、开发等)的反馈,根据反馈结果进行及时的修复、调整、或者优化。
为了保障快速反馈/持续测试实践活动的有效开展,通常需要增加质量门禁,并确保质量门禁的严格执行。
1.3 测试右移
测试右移是跟测试左移对应的,就是将测试活动从独立测试阶段右移到生产环境。
但因为生产环境的特殊性,测试右移又不是测试活动的简单右移,而是通过一些实践活动获取生产环境下用户行为、日志等质量相关信息,利用这些信息来给前期的需求、开发和测试工作提供反馈,促进相应工作的优化改进,以更好的做好质量内建。
测试右移本身不能直接内建质量,但是可以帮助更好地质量内建,所以我认为测试右移也是质量内建不可或缺的核心内容之一。
这部分的内容比较多,之前有过详细的介绍,此处不再赘述。欢迎参考文章《测试右移——生产环境下的QA》阅读更为详细的内容。
1.4 全员参与
测试左移、快速反馈和测试右移都不是某个单一角色/人员可以做到的,需要不同角色的不同技能和不同视角的输入,质量人人有责,需要全员参与并且能承担起质量职责才行。
全员参与不仅是很多实践活动需要大家一起参与,还有很重要的一点是团队内部需要有足够的沟通和信息共享。只有信息足够透明,每个人都清楚质量目标、质量状态和风险,才能真正发挥主人翁精神积极地参与,才能发挥团队每个人最大的价值。一定要警惕团队“蘑菇种植”。
这部分内容之前也有过非常多的分享,欢迎参考:《团队对质量负责,“我”可以不负责?》、《敏捷测试的指导性原则》、《说好的团队为质量负责呢?》等文章。
2. 质量内建典型实践
综合来看,质量内建的典型实践通常有(但不限于)下图这些:
不管是传统开发模式还是敏捷迭代式开发模式,软件开发生命周期都会有需求分析、开发实现和线上使用三个阶段,只是敏捷模式下需求和开发是迭代式进行,在时间上不是界限清晰的阶段。
这里为了描述方便,暂且将这些实践分成三个阶段来描述,事实上实践活动跟阶段也不是关联非常紧密的,遵循测试左移、快速反馈、测试右移和全员参与这几个核心思想才是关键所在。
2.1 需求分析
这里强调四个我认为跟需求分析密切相关的典型质量内建实践,分别是需求澄清、行为驱动开发(BDD)、实例化需求(SbE)和需求评审。
需求澄清:需求的理解和澄清作为测试基本职责之一,在 《基础篇》中有较为详细的介绍,请移步参考。不过,在这里需要补充的是不仅测试要参与需求澄清,还需要其他相应的角色协同参与,比如开发人员、技术负责人、技术架构师等。
行为驱动开发(BDD):关于 BDD,很多人误认为是一种测试方法,但其实 BDD 主要是为了三方更好地对需求达成一致认识,只不过通过 BDD 方式产生的需求能够很好地指导自动化测试的开展。更多详情,请参考我之前的文章《说起 BDD,你会想到什么?》。
实例化需求(SbE):SbE 的核心思想跟 BDD 类似,但强调了一点要将需求描述通过实例来说明,以更好地发现漏掉的需求,让需求更完整、更容易被多方理解和澄清。
需求评审:需要开发和测试跟业务分析人员一起讨论确认需求,可能是正式的会议针对某个特性(大块需求)的评审,也可以是针对单个需求条目或敏捷用户故事进行线下评审。如果前期需求澄清过程中对需求的讨论已经比较透彻,这里的评审就会比较轻量级,由测试人员(开发按需参与)自行安排时间评审即可。
这些实践都是为了在需求分析阶段让团队对需求达成一致的理解,确保需求的质量,减少后期因需求问题带来的返工和浪费。
2.2 开发实现
需求源头的质量控制好了,接下来就是在开发实现阶段持续地通过快速反馈的方式确保每一步工作的质量,下面的实践都是为此服务的:
技术方案讨论:不是要介绍这个实践怎么做,而是要提醒在做技术方案讨论的时候测试要尽量参与。一方面,测试清楚了解技术方案,才能更好地设计相应的测试策略,更完备的进行测试;另一方面,测试基于自己对系统的了解,可以给技术方案的讨论提供输入,比如系统重点需要考虑和关注的问题等。可能有人会觉得测试技术水平跟不上,参与价值不大,但我想说的是不参与就不会有进步,只要参与了就一定会有收获,从长期来看,不管是对个人还是对团队整体都是非常有价值的。
需求条目启动:也叫用户故事启动(Story kickoff)、开卡等。对于单个可开发需求,在开发人员要开始编码前进行的再次澄清和确认,主要是确认其中的验收标准是否不够完备、是否大家都理解一致了。形式要求尽量轻量级,在开发人员电脑前完成即可,需要业务分析、开发和测试共同参与,时间一般不要超过 15 分钟。
需求条目验收:跟启动是配对的,也叫用户故事验收(Desk check/Shoulder check/Story signoff)、结卡/验卡等。同样在开发机器前面完成,一般由开发将功能演示给业务分析和测试人员,大家确认需求中的正向路径是否都已经开发实现了。更多详情可参考文章《高效用户故事验收》。
测试用例设计:在 《基础篇》有对测试用例设计作详细的介绍,从质量内建的角度来看主要是想说测试用例设计尽量早点做,而且对于用例设计的形式可以相对灵活些,列举需要关注的测试点才是关键,从快速反馈的角度,不建议过于注重形式和流程。
测试驱动开发:TDD,常见的有单元测试驱动开发(UTDD)和验收测试驱动开发(ATDD),通过先写测试的方式驱动设计的完备性。Thoughtworks 同事刘冉老师有多篇关于 TDD 的文章,请移步他的网站「刘冉的思辨悟 ( http://liuranthinking.com )」查阅参考。
代码评审:Code review,也叫代码回顾。有团队成员聚集在一起做回顾的,也有独立线下评审的模式。Thoughtworks 同事伍斌道长的文章《Code Review: 超越“审、查、评”的代码回顾》有关于 code review 非常详细的讲解,请移步参考。
自动化回归测试:根据测试分层理论,自动化测试可能包括单元测试、接口集成测试和端到端测试。通常单元测试是开发人员编写,而接口集成测试和端到端集成测试可以开发和测试协作完成。关于自动化测试相关文章比比皆是,这里推荐如下内容供参考:
Thoughtworks 洞见自动化测试文集 ( https://insights.thoughtworks.cn/?s=%25E8%2587%25AA%25E5%258A%25A8%25E5%258C%2596%25E6%25B5%258B%25E8%25AF%2595 )
刘冉老师网站的自动化测试文集 ( http://liuranthinking.com/automatedtesting/ )
单元测试评审:单元测试评审一般发生在需求条目验收环节,详情参考文章《QA 评审底层测试的价值》。
持续集成:持续集成(CI)概念大家并不陌生,但是有效实施却不是那么容易。常见的反例有:
光有持续集成流水线,但是流水线上啥也没有,没有代码扫描、没有自动化测试、没有质量门禁;
流水线有接入代码扫描,但是扫描出问题没有及时修复;
自动化测试没有在流水线上频繁执行,或者执行失败不能及时修复;
代码没有频繁提交;
……
更多内容,推荐参考 Thoughtworks 洞见文章《持续集成理论和实践的新进展》和《对于持续集成实践的常见问题的解答》。
自动化/持续部署:自动化部署在提高效率的同时还可以减少手工部署引入的问题,让部署能够更频繁更持续地发生。这部分内容可以参考 Thoughtworks 洞见文章《持续集成和交付流水线的反模式》。
技术债管理:还记得前面那个布满杂乱无章电线的图吗?软件开发过程中引入的技术债如果没有得到有效管理,软件内部也会乱成那个样子。关于技术债管理,推荐 Thoughtworks 同事麻广广的文章《软件架构治理之技术债的前世今生》。
探索式测试:探索式测试有助于发现一些潜在的不易察觉的缺陷,是非常推荐的一个实践。具体做法和建议在《基础篇》中对探索式测试有详细介绍。
客户验收:英文叫 Showcase,就是给客户、业务方演示开发实现的特性。Showcase 也有很多常见误区,请移步文章《敏捷实践 Showcase 的七宗罪》。
缺陷分析:缺陷分析对质量内建的帮助主要是通过分析找出问题根因,在后续的开发工作中提前避免以预防更多的缺陷暴露。如何做好缺陷管理和分析?请参考下列文章:
质量状态报告和质量风险分析:请参考《基础篇》中“测试职责之五:质量反馈与风险识别”部分的介绍。
回顾会议:回顾会议通过总结和分析过去一段时间团队发生的事情,是关于团队整体健康状态的。我之所以将回顾会议列为质量内建的典型实践,是因为咱们前面讨论过了影响质量的因素涉及到方方面面,自然就跟团队的健康有着很大的关系。利用好回顾会议这个实践,及时发现问题并采取对应的改进举措,将是非常有价值的。关于回顾会议的高效开展,可以参考 Thoughtworks 洞见文章《高效回顾会议的七步议程》。
2.3 线上使用
软件产品发布到线上,质量内建相关实践都是跟测试右移有关的,这是一个很大的主题,之前有过系列文章的介绍,相关实践可以参考下列文章:
04 写在最后
测试基本职责是测试人员必备之基础技能,但测试的体系化思维构建不能仅局限于测试工作本身,当我们跳出测试,从质量的角度来看,又是另一番景象。
希望本《进阶篇》能够帮助各位测试同仁从质量的角度拓宽视野,增加大局观,让质量保障工作做得更顺畅。
同时,也欢迎大家关注我的自出版小书《不止测试》,书中介绍的其实是测试人员或者 QA 需要关注的超出测试基本职责之外的内容。