探索式测试落地实践
历史与简介
早在 1984 年,Cem Kaner 就提出了探索式测试(Exploratory Testing),并首次定义它是“一种测试风格,主要是强调个人的自由与责任,让独立的测试人员可以持续的并行的通过相关的学习,测试设计,测试执行等活动来改善测试工作的质量”。
然后到了上个世纪 90 年代,Cem Kaner 又在他的书《Testing Computer Software》中第一次正式发布了探索式测试这个方法论,从此它正式进入测试领域,并且引起了业界的关注,很多测试人员也开始实践这种测试方法。
从 Cem Kaner 给出的这个定义可以看出,探索式测试的提出主要是为了解决当时测试成本高,效率低,僵化和墨守成规的问题。所以探索式测试最主要的目的就是节约测试成本,以最少的资源投入发现最多的缺陷与问题,从而实现快速测试,并获得高的测试投资回报比。但是当时定义的探索式测试最大的问题是难以知道测试过哪些用例,从而难以度量探索式测试 。
后来 James Bach 根据自己的理解重新定义了探索式测试,他将传统的测试行为分为检验(Verification)和测试(Test)。所谓的检验就是使用确定的测试步骤或者测试脚本来检验系统,而测试则是通过对未知的探索、学习和实验等一系列科学手段,发现并设计出新的测试用例,最后执行这些测试用例来验证系统。因此他认为真正的测试都需要探索,而探索式测试的核心则是测试分析和测试设计,所以如果要度量探索式测试的产出,则应该和测试工作一样,度量测试分析和测试设计的产出,即测试用例。不过很多测试人员在实施探索式测试的时候并不会产出测试用例,所以导致探索式测试很难度量。良好的可度量的探索式测试需要产出测试用例或者测试点,其中测试用例也分很多种不同类型(参见《洞见101之测试用例编写和管理》),一般探索式测试产出的用例会使用场景式(Scenario),而不是步骤式(Step),从而可以节约一定的成本。
注:本文后面都假设资源足够,以测试用例作为产出进行讨论。如果是资源不足的项目,后文中的测试用例替换成测试点即可。
当前现状
在瀑布式开发流程中,探索式测试一般都是在功能开发完成之后,甚至回归测试完成之后,在有额外资源和时间的情况下由测试人员专门安排时间进行。如果没有足够的资源和时间,一般则不会进行探索式测试。除了测试人员专门安排时间进行的探索式测试,还有由非专业测试人员进行的一些测试活动,是一种非专业性的探索式测试,比如 Bug Bash,用户测试等。这些由非专业测试人员进行的测试的测试用例都非常随机,重复度较高,有效率较低,所以很难度量测试的覆盖率和测试的有效性。不过 Bug Bash 和用户测试的投入成本相对较低,所以使用也比较广泛。但是由专业的测试人员进实施的探索式测试,由于投入成本相对较高,并且很难度量产出,所以实施并不广泛和深入。
敏捷开发中敏捷测试的实践核心是快速反馈,这与探索式测试中的快速测试不谋而合,并且敏捷测试中的很多实践和探索式测试相似,比如注重测试分析和设计,避免繁琐的测试管理,不需要包含详细操作步骤的测试用例等。在敏捷测试中非常注重探索式测试,不管是测试前移实践中对业务需求和验收条件的测试分析,还是 Desk Check 和故事验收中的快速测试,亦或故事测试和系统测试中的探索式测试,都是探索式测试在敏捷测试中的实践之一。所以探索式测试在敏捷开发中是非常重要的一个实践,能有力的发现各种问题。
所以当前探索式测试之所以难以实施,其最大的难点有两个:第一个是难以度量产出和收益,所以大部分项目中,管理层都不愿意对探索式测试进行投入;第二个是没有明确实施步骤,测试人员难以系统化的实施,往往做起来感觉像随机测试,稍微做久一点就容易迷失了,不知道下一步应该怎么做。不过在敏捷开发的敏捷测试中,实施探索式测试有天生的优势,不管是实施步骤,还是度量管理,都十分适合使用探索式测试。
敏捷开发中的实践
在敏捷开发的敏捷测试中,最为重要的是通过对业务需求和验收条件的测试分析,以及和其他角色的合作,可以设计出覆盖率更高,有效性更好的探索式测试用例;其次根据故事卡生命周期(参见《敏捷测试之我们的敏捷测试实践》),可以明确的给出探索式测试的实施步骤,从而可以系统化实施探索式测试;最后通过测试用例度量探索式测试的产出。
探索式测试的测试分析和测试设计
探索式测试最重要的是测试分析与测试设计,但是这两部分也是最容易被忽略和误解的。没有良好的测试分析和测试设计,是不可能做好探索式测试的,所以一般能做好探索式测试的都是测试经验和技能丰富的测试人员。因为只有这样专业的测试人员才能在短时间内很好的完成测试分析和测试设计的工作。
测试用例分布图
图中高频高危探索区主要指验收条件的外延部分和风险较高的业务,而针对这部分进行探索式的测试分析,可以获得很多高价值的测试用例。而对于低频普通探索区,主要指重要性和价值很低的业务,或者是一些很难执行到的场景,或者就算出错也不会影响用户的正常使用的业务等。
除了明确的业务需求和验收条件,所有的测试用例都可以通过探索式测试得到,其中基础的用例可以使用外延关联法得到,而高级一点的测试用例可以用系统风险法以及其他各类测试分析与设计方法得到,比如《探索吧!深入理解探索式软件测试》与《探索式测试实践之路》等书中介绍的测试分析与设计方法。但是资源都是有限的,所以不可能在一个项目中针对所有的业务都实施各种类型的探索式测试方法,所以我才总结了基础的外延关联法和系统风险法,用以指导常规的情况下如何快速的实施探索式测试。
其中外延关联法,是指根据已有的业务需求和验收条件,梳理出每个需求验收点,并且通过扩展和打破这些需求验收点来设计测试用例,或者关联这些测试用例来进行测试。这部分用例大部分在高频高危探索区。
而系统风险法,则是指通过梳理整个系统的所有业务场景和技术架构,找到最为重要并且风险最高场景和技术点,并测试这些场景和技术点是不是符合预期。这部分用例大部分也在高频高危探索区。
其他探索式测试方法还有很多,这里就不再赘述,学习这些方法并且能融会贯通,是可以极大的帮助测试人员设计出更好的测试用例。但是如果能熟练的使用外延关联法和系统风险法,就可以满足敏捷测试中对于探索式测试的基本要求。
探索式测试的执行
在传统瀑布开发模型中,测试往往由独立的测试部门中的测试人员在专门的测试阶段进行,所以探索式测试一般也是在这个专门的测试阶段中进行,但是在敏捷开发的敏捷测试中,没有专门的测试部门,专业的 QA 人员参与到软件开发的整个生命周期中,并在每个阶段都可以进行探索式测试,或者赋能给其他角色,比如 BA 或者 Dev 等,让他们自己做探索式测试。所以在敏捷开发中,探索式测试可以由不同角色的人在软件开发的整个生命周期中的每个阶段进行,见下图:
敏捷测试中的探索式测试图
在每个阶段中,都包含以下部分或者全部步骤:
- 测试分析和测试设计
- 测试用例记录
- 测试用例执行
- 测试结果记录
其中有些阶段只有测试分析、测试设计和测试用例记录工作,比如 STORY CONFIRMATION 和 KICKOFF 中,因为这个阶段软件还没有开发出来,只能对需求进行测试,并帮助实施 TDD 和需求的传递。而在故事测试和系统测试中,则需要执行上面的所有步骤,从而完整的实施探索式测试。并且一般这四个步骤都是并发在做,比如针对一个验收条件或者业务场景,一边分析设计,一边测试,一边记录,然后再分析设计,再测试,再记录,直到很难再分析和设计出重要的测试用例了。接着就可以针对下一个验收条件或者业务场景使用这四个步骤进行探索测试。
其中测试分析和测试设计,按照外延关联法可以有效的完成基础的探索式测试。但是如果要进一步做深入的探索式测试,则需要使用系统风险法。对于测试用例执行则是通过手动或者自动的方式来执行测试用例,最终测试结果主要详细记录那些没有通过的用例和发现的问题。
探索式测试的产出度量
通常情况下,探索式测试的度量主要是发现了多少缺陷。而缺陷其实只是测试的副产物,而测试用例才是探索式测试的主要产物。通过探索式测试中的测试分析和测试设计,可以产出相应的探索式测试用例,而这些新的测试用例就是探索式测试最为重要的产出,而度量探索式测试则最主要依靠这些有效的测试用例。比如可以度量单位时间内探索并设计出来的新测试用例,或者新的测试用例增加了多少测试覆盖率,或者通过探索获得了多少新的自动化测试用例等。但是要注意一点,如果对同一个项目持续长时间并且多次做探索式测试,新产出的测试用例应该会逐步减少,所以度量的指标随着探索式测试的持续进行应当适当减少。
总结
探索式测试的度量和落地一直都是其最大的两个问题,而测试分析和测试设计就是解决这两大问题最有效的方法。通过有效的测试分析和测试设计,产出的测试用例是度量的基础。所以如果想做好探索式测试,需要熟悉测试相关的各种分析和设计方法,然后在持续迭代,各方协作并且思维自由的状态下不断的探索并产出高质量的测试用例,从而可以使用这些测试用例来帮助团队完成各种测试和质量相关的工作,更好的实施质量内建,开发出高质量的软件。
最后本文介绍的方法也可以作为一个测试方法和技术对大模型进行训练和微调,从而让大模型来辅助我们做探索式测试,从而提高探索式测试的效率。