在没有蜕变测试的时代,传统软件测试的原理是:给定输入,观察被测软件的输出,并与期望输出进行对比,基于对比结果判断软件是否存在缺陷,如下图所示:
传统测试存在一个基本假设,那就是:软件的期望输出是已知的。然而,许多情况下,软件的期望输出并不是已知的,或者说非常难知道。例如:
对于这些近乎“不可测”的场景,传统意义的软件测试技术爱莫能助了,于是乎蜕变测试诞生了。
蜕变测试(metamorphic testing)是一种新型软件测试技术。蜕变测试的科学定义是:识别被测软件所具有的蜕变关系(metamorphic relations),通过检查这些蜕变关系 是否成立 来判断软件是否存在缺陷的技术。
理解: 在蜕变测试中,我们并不需要知道测试的正确输出是什么(或者说我们很难知道测试的正确输出是什么),但是我们可以确定输出1与输出2是存在某种关系的。例如我们知道输出1和输出2存在“包含关系”,那么我们不需要去验证输出1与输出2的正确性,而只需要验证输出1和输出2是否存在“包含关系”即可。
举例说明,如下图所示,在测试谷歌搜索引擎时,有两个用例,分别搜索 关键词“car” 和 关键词“autonomous car”。这里隐含着一种蜕变关系:由于后者限定了输入关键词car的属性,因此后者的搜索结果应该是前者的一个子集。
如果从最终搜索结果发现子集关系不成立,例如:autonomous car的搜索结果数量大于car的搜索结果数量,或者autonomous car的搜索结果包含了一个不在car搜索结果范围内的结果,则说明:子集蜕变关系没有成立,搜索程序可能存在缺陷。
那么,怎么进行蜕变测试呢?一般来说,蜕变测试主要包含四大步骤。
如果说软件测试最难的是期望输出的生成,那么 蜕变测试最难的就是蜕变关系的生成 。生成蜕变关系没有一个标准套路,需要结合应用场景和上下文。
上面我们介绍的例子中,两次搜索结果是包含的关系。在搜索查询类应用中,蜕变关系还可以有以下类型:
注:蜕变关系的挖掘和生成,是蜕变测试研究的热点,也是蜕变测试应用的难点。
蜕变测试包含多对输入/输出,因此蜕变测试用例包含多个测试用例。
蜕变测试用例由两部分组成: 起始测试用例(source test case) 和 跟随测试用例(follow up test case) 。通过对其实测试用例的输入进行变换(根据蜕变关系进行变换),得到跟随测试用例。
从应用角度来说,蜕变测试主要用在可测性不好的场景,例如机器学习系统、数据查询系统、科学计算系统、仿真与建模系统等。
需要注意的是,蜕变测试只是在一定程度上缓解软件的不可测性或者可测性不好的问题,而不能根本上解决这些问题。毕竟,蜕变关系只是被测软件众多属性中的一种。蜕变关系成立,不代表测试就进行得充分。
就像大师所言,软件测试只能证明软件存在缺陷,不能证明软件不存在缺陷。蜕变测试,更是如此。