这次想和大家聊聊探索式测试的问题,这次是用涂鸦的方式。
什么是探索式测试
探索式测试(Explorer Testing)最早是由测试专家CemKaner博士在1983年提出的,最早讨论探索式测试的书,应该是《软件测试的经验与教训》(由CemKanner,JamesBach和BretPettichord合著),不过这书现在已经买不到了。
借敏捷的东风,探索式测试这个概念在中国测试行业还是小火了一把的:传统的测试流程,需求分析、用例设计什么的,很费工夫不说,还完全架不住需求频繁的变化,在敏捷下,这一套严谨的做法反而成了项目的“负担”。于是大家把视线转移到了探索式测试上,希望探索式测试能够减少测试在文档上的投入,可以更多的聚焦产品,进行更快速的测试。
在这样的思路下,很多测试者跃跃欲试,开展了轰轰烈烈的探索式测试活动。公司的、团体组织的各种线上线下的活动也如雨后春笋般出现了。但我发现很多同学在参加了探索式测试后反而迷茫了,最多的问题是,探索式和我以前的测试到底有什么不同?
有人说探索式测试更强调测试方法,掌握探索式测试后测试者就可以用各种手段来折磨软件系统以发现系统的bug,但很多测试者会说我用所谓的传统测试,也很会找bug啊。有人说探索式测试更强调主观能动性,能够更主动的去做发散测试,探索系统的bug。但测试者又会说,我在传统测试中也是这样做的啊。
我们究竟该如何去理解探索式测试呢?
首先,探索式测试是一种软件测试风格(style)。
而不是一种具体的软件测试技术(比如性能测试,等价类分析等)。
也不是在某个测试阶段才能做的测试。
更不是敏捷下特有的软件测试方法。
探索式测试作为一种思维方法(approach),强调要根据当前的实际情况(context-driventesting,很多材料翻译的都是“上下文语境驱动”,非常不好理解,我觉得用中国的老话来解释就是要根据当前的实际情况,具体问题具体分析)来选择最合适的测试技术,进行测试。至于你用的是什么方法,什么技术,在何时展开,用的是敏捷还是瀑布都没有关系。
这就可以解释大家的疑惑原因了——探索式测试并不是什么新的东西,我相信无论你现在用的是怎样的测试模式,探索式测试多多少少都会在你的测试思维中。只是我们可能没有意识到,没有系统的去思考总结过,更没有通过刻意的去练习去提升自己在这方面的能力。所以在我们看到探索式测试的时候,才会觉得既熟悉,又陌生。
我们今天的话题,就是想和大家一起来梳理一下探索式测试,把大家有些忽视的探索式测试的这部分测试思维拿出来,来做一次系统的总结和思考。
探索式测试本质是测试策略
作为测试者,你也许没有意识到,探索式测试,本质是一种策略。
和世界万物一样,被测对象也是时刻处于变化和发展中的——每一行代码的改变,都会让被测对象变得和之前不同。每个版本都是一个不同的产品,这就需要我们根据每个版本的特点来选择不同的测试方法来测试它。
找到这些不同本身就是个探索的过程——被测系统的复杂度决定了我们不可能一下子就看到系统所欲的变化,这就需要我们一边探索,一边根据系统的反馈来总结,调整下一步的探索点。这就是探索式测试最重要的思维模型CPIE模型,如下图所示:
收集(Collation):收集所有关于测试对象的信息并去理解这些信息。
划分优先级(Prioritization):对所有需要测试的任务进行优先级的划分。
分析调研(Investigation):对测试的任务进行仔细分析,预测可能输出的结果。
实验(Experimentation):进行测试实验,确认测试结果和预期是否符合。分析是否需要修改测试策略和方法。如有需要,进入“收集”阶段。
事实上,如果我们在测试中可以做到“测试—总结—再测试”,就是在践行探索式测试了。不过现在我们是把探索式测试作为方法论来讨论,和我们无意识做的探索式测试相比,CPIE强调了“优先级”。
讲到这里,我们先讲一下“发散测试”这个概念。很多同学都不会区分探索式测试和发散测试,很多同学甚至将两者直接划等号。事实上,发散测试和探索式测试都需要对探索被测系统,但发散测试是想到哪里就立马去测试,天马行空很随意;而探索式测试需要在测试之前分析一下,看看这个探索是否值得(优先级)。除此之外,发散测试在测试之前不太关心预期结果,就是测了再说;探索式测试会在测试之前分析结果——显然结果分析更有利于我们确定这项测试的优先级。
为什么我们说探索式测试的本质是一种测试策略,这是因为探索式测试需要我们有“取舍”的能力。不是说我们把测试思维做得够发散,能够想到别人想不到的测试点就够了,就厉害了,还要会分析,懂得如何在有限的时间中去舍弃掉一些测试项,然后可以更深入全面的对测试重点进行测试。
进行探索式测试
在探索式测试中我们该如何“取舍”呢?这就要从“进行探索式测试”来开始讲了。
确定测试范围
和所有测试一样,我们先要确实测试的范围。
探索式测试的范围可以分为如下三类,如下图所示:
“全局场景探索”:准备进行探索的对象是整个系统。
“特性漫游探索”:准备进行探索的对象是整个特性。
“局部功能点探索测试”:准备进行探索的对象是某个具体的功能。
根据被测对象的特点来选择测试方法
接下来我们可以分析我们即将要测试的对象的特点,然后根据它的特点来选择合适的测试方法。如下图所示。
如果“特性”同时具备了多个区域的特征,那就将这个特性分别划到这些区域中去。如果我们是对一个产品中的特性来划分区域,划分完成后,可能会像图中所看到的那样,存在相互重叠的情况,这没关系,你可以用多种方法来进行测试。
接下来我们就来看看这些不同区的测试方法:
1.历史区测试方法
“历史区测试法”针对的“老代码”,即在前几个版本就已经存在的软件特性,也包括那些用于修复已知缺陷的代码。
“历史区测试法”是一种有效的测试方法,因为对于软件的“缺陷”来说,历史常常会重演——我们经常在测试中发现,之前修复的缺陷在后面测试的时候又发现了,或是在后面的测试中又发现了类似的缺陷,因此多花一些时间重新测试那些曾含有很多缺陷的代码是特别重要的。
下表总结了“历史区测试法”中包含的“探索式测试方法”,供读者参考:
恶邻测试法:就是指那些缺陷横行的代码段,测试人员应该在这些区域尽量多花时间。
博物馆测试法:重视老的可执行文件和那些遗留代码,另外还包括累积许久没有执行过的用例,确保他们和新增代码享受同等待遇。
上一版本测试法检查那些在新版本中无法再运行的测试用例,以确保产品没有遗漏必需的功能,也就是说如果当前产品构造是对先前版本的更新,必须先运行先前版本上的支持的所有场景和测试用例。
2.商业区测试法
“商业区测试法”针对的是“销售特性”。所谓的“销售特性”,指的是产品的重要功能和特性,是测试时需要重点测试的对象。
“商业区测试法”包含的主要测试方法如下:
指南针测试法:主要要求测试人员通过阅读用户手册,场景及产品需求进行相关的测试。
卖点测试法:对那些能够吸引用户的特性进行测试,至于哪些特性能够吸引用户,可以向销售人员咨询,或者拜访客户。
地标测试法:主要是寻找测试点,明确测试项,这里的测试点就是“地标”。
极限测试法:向软件提出很多难以回答的问题。比如如何使软件发挥到最大程度?哪个特性会使软件运行到其设计极限?哪些输入和数据会耗费软件最多的运算能力?等等。
快递测试法:要求测试人员专注于数据,即数据从输入到输出展现给客户或页面过程中,数据执行的流程。
深夜测试法:当我们不对测试对象操作时,测试对象能否会自动完成各种维护任务,将数据归档,自动记录发生的异常情况等。
遍历测试法:通过选定一个目标,然后使用可以发现的最短路径来访问目标包含的所有对象。测试中不要求追求细节,只是检查哪些明显的东西。
3.娱乐区测试法
“娱乐区测试法”针对的是“辅助特性”,也就是那些并不是那么重要的特性的测试。
“娱乐区测试法”包含的主要测试方法如下:
配角测试法:专注于某些特定的特性,它们虽然不是那种我们希望用户使用的主要特性,但和那些主要的特性会一同出现。它们越紧邻那些主要功能,越容易被人注意,所以必须给予这些特性足够的重视,不能忽视。
深巷测试法:测试产品特性的使用情况列表中排在最下面的几项特性(最不可能被用到的或是那些最不吸引用户的特性)。它的变种是“混合测试法”,试着把最流行和最不流行的特性放在一起混着测。因为开发人员可能从来没有预想过它们会在这样的场景中被混合在一起。通宵测试法
“通宵测试法”是测试软件的长时间运行后,各功能模块是否正常,有点像稳定性测试。这个方法很容易和“深夜测试法”混淆,但是测试侧重点不同:“深夜测试法”测试的是测试对象的自动处理能力。
4.破旧区测试法
“破旧区测试法”针对的是“问题高发特性”。对这些让人头痛的“问题高发特性”,“破旧区测试法”的测试思想就是继续“落井下石”:“输入恶意数据”、“破坏操作”、“修改配置文件”等等,所有这些你能想到的“有害”的事情,都往这些特性上招呼就对了。
“破旧区测试法”包含的主要测试方法如下:
破坏测试法:就是指那些缺陷横行的代码段,测试人员应该在这些区域尽量多花时间。
反叛测试法:要求输入最不可能的数据,或者已知的恶意输入。你见过去酒吧不喝酒点果汁的么?反叛思想要求输入最不可能的数据。
强迫症测试法:强迫软件一遍又一边接受同样的数据,反复执行同样的操作。此种思维方式,常常打破了开发人员设计代码的思路,他们预想着你会按步骤操作,却不曾考虑过你反复的执行第一步应该如何处理。
5.旅馆区测试法
“旅馆区测试法”针对的是“平台或维护特性”。这些特性的特点是容易被忽视,而“旅馆区测试法”就是让我们再回过头去测试一些经常被忽视的或再测试计划中较少描述的次要及辅助功能的方法。
“旅馆区测试法”包含的主要测试方法如下:
取消测试法:启动相关操作,然后停止它,查看测试对象的处理机制及反应。例如在功能进行中使用esc键,取消键,回退键,关闭按键或者彻底关闭程序等。
懒汉测试法:做尽量少的实际工作,让程序自行处理空字段及运行所有默认值。
6.旅游区测试法
“旅游区测试法”针对的是“噱头特性”。这种测试方法的特点是关注如何快速访问文件的各种功能,测试目的就像方法的名称一样,只是为了到此一游。
“旅游区测试法”包含的主要测试方法如下:
收藏家测试法:测试人员通过测试去收集软件的输出,将那些可以到达的“地方”都到达一遍,并把观察到的输出结果记录下来,收集得越多越好。
长路径测试法:访问离应用程序的某个开始点尽可能远的特性。哪个特性需要点击N次才能被用到?哪个特性需要经过最多的界面才能访问?主要指导思想是到达目的地之前尽量多地在应用程序中穿行。
超模测试法:要求测试人员去关心那些表面的东西,只测试界面。测试中注意观察界面上各种元素。它们看上去怎么样?有没有被正确的绘制出来?变化界面时,图形用户界面刷新情况如何?如果软件用颜色来传达某种意思,这种信息是否一致?界面是否违反了任何惯例或标准?
测一送一测试法:测试同一个应用程序多个拷贝的情况。测试程序同时处理多个功能要求时,是否正常,各功能之间同时处理时,是否会相互影响。
7.其他区测试法
“其他区测试法”包含的主要测试方法如下:
恶邻测试法:就是指那些缺陷横行的代码段,测试人员应该在这些区域尽量多花时间。
博物馆测试法:重视老的可执行文件和那些遗留代码,另外还包括累积许久没有执行过的用例,确保他们和新增代码享受同等待遇。
上一版本测试法:检查那些在新版本中无法再运行的测试用例,以确保产品没有遗漏必需的功能,也就是说如果当前产品构造是对先前版本的更新,必须先运行先前版本上的支持的所有场景和测试用例。
设计探索测试地图
接下来我们就可以使用相关的测试方法,来设计探索式地图了:
并对得到的测试项目,确定测试结果,确定测试优先级。再根据项目的时间确定本次探索式测试的测试内容。
开始探索式测试
确定好了探索式测试项后,就可以开始测试了。
之前得到的测试项目可能会随着测试的进行,变得不合适。所以我们在探索测试一段时间可以再针对测试情况做一下总结,再更新测试项目。
有时候,我们可能会停下来重新收集系统的信息,或者准备新的测试环境,这些都是可以的,都是允许的。
有的参考材料上建议把探索式测试的时间分为几个固定的时间钟,比如每测试1小时,停下来总结、更新测试项目1小时,再开始测试1小时,如此循环。我觉得这个方法不错,但是时间钟的长短需要根据被测对象的特点来确定。