首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

选择性回归测试

本项目的github地址:

https://github.com/slxiao/rts

1. 回归测试

回归测试是软件测试的重要内容。在敏捷和DevOps时代,要实现持续集成和持续交付,回归测试不可或缺。每一次代码提交、每一次软件集成、每一次产品交付,都需要经过回归测试验证。回归测试是检验以上工作的质量的“试金石”。是骡子是马,拉出来跑一跑回归测试。

然而,具有重要价值只是回归测试的一个方面。万物都有两面性。回归测试的另一面是,它需要相当高的成本。这是为什么呢?

我们知道,随着产品功能的增加,回归测试用例数量会越来越多。这里的回归测试可能包含多个级别的测试(单元测试、模块测试、集成测试、系统测试等)。每一次代码提交,无论改动量大小,由于可能对系统产生影响,因此通常会执行尽可能多(很多时候是全部)的回归测试,以确保所有已有功能均没有被破坏。然而,执行的测试越多、执行时间越长,就意味着反馈测试结果的速度越慢,软件开发的时间成本就越高。

另外,在强调快速迭代和增量开发的背景下,无论是代码提交的频率、还是软件交付的频率,都大大提高。这意味着回归测试集的执行频率也会很高,单位时间内需要重复执行的回归测试数量就越多。必然需要大量的硬件环境和资源才能支撑如此高频的回归测试。

还有,由于自动化回归测试固有的Flakiness性质(

“投降论”和“速胜论”都不可取,消除Flaky Tests是一场持久战

),回归测试很难做到100%稳定。在大量用例高频执行的背景下,回归测试的不稳定性会被放大。要处理这种不稳定性,无论采用被动手段(重新执行)还是采用主动手段(人工排查)都需要消耗成本。

面对“价值”和“成本”双高的局面,我们不禁要问,能否在保持回归测试价值的前提下,有效降低回归测试的成本呢?

2. 选择性回归测试

降低回归测试成本的一个办法就是从回归测试转变为选择性回归测试。所谓选择性回归测试,就是在因为代码改动需要执行回归测试时,只选择回归测试用例集合中可能受到本次改动影响的子集执行。

选择性回归测试的可行性在于:一次代码的改动不太会对所有回归测试用例产生影响。另外,根据迭代开发的要求,我们通常倾向于将较大的改动分多次提交。也就是说,每次代码提交只会包含比较小的改动。这意味着,真正受影响的测试用例,应当只占全部测试用例的小部分。这进而意味着,选择性回归测试有潜力显著降低回归测试成本。

根据实现方式,选择性回归测试分为两种:

(1)手动选择:由每个代码提交者根据自己的改动情况,手动选择本次提交需要执行的回归测试用例。

(2)自动选择:由程序自动选择每一次提交时需要执行的回归测试用例。

在大规模回归测试的情况下,人工识别需要花费每一位代码提交者的工作量。更重要的,人工容易产生疏忽,将bad code合入主干代码,破坏主干代码和持续集成/持续交付流程,造成严重的后果。

那么,如何实现自动选择?首先,一个回归测试选择程序,需要满足以下三个要求:

(1)安全:所有受当前改动影响的用例都能够被选择。

(2)高效:选择用例的时间应当小于执行未被选择的用例的时间。

(3)准确:不受改动影响的用例没有被选择。

一般来说,可以通过静态或者动态分析来建立测试用例与代码改动之间的相关性。然而,由于计算机程序内在和外在的复杂性,要实现满足上述三个条件的自动回归测试选择是一件相当有挑战的事情。事实上,“回归测试选择”是近十几年来软件工程领域比较活跃的研究方向之一。例如,一篇2015年度的博士论文就是专门研究这个方向的,作者是UIUC计算机博士Milos Gligoric,论文中主打的就是面向Java的测试用例选择工具Ekstazi

3. 面向Robot Framework的回归测试选择算法

Robot Framework是一个通用的、关键词(keyword)驱动的测试自动化框架。在Robot Framework中,测试用例由suite文件组成,每个suite包含一个或多个test case,每个case则由若干Robot或者Python语言实现的keywords组成。整体上呈现模块化结果。

基于Robot Framework开发自动化测试,实践的是测试用例即代码(test-case-as-code)理念。这意味着,我们需要像编写软件代码一样编写测试代码,需要像管理软件代码一样管理测试代码。例如,我们的某个基于Robot Framework的自动化测试项目,包含200个左右的源文件和20000多行代码,就是采用git来管理的。

敏捷的要义之一就是拥抱变化。在实践中,被测软件的变化是常态。这经常意味着自动化测试用例也需要改变。另外,针对测试用例的优化和维护也是一种日常的工作。因而,测试用例仓库的改动是一件高频的事情。据统计,上述Robot Framework项目,在过去三个月,90%的文件都被修改过;在每一个工作日,平均有15个文件发生修改。

测试代码的改动,同样需要经过回归测试的验证。那么,如何在每次测试代码改动时,自动选择受影响的测试用例呢?

这里,介绍一种面向Robot Framework的回归测试选择算法(Robot Test Selection, RTS)。项目的github地址是:https://github.com/slxiao/rts,欢迎关注

RTS算法的描述如下。

输入:候选测试suite列表、改动文件列表。

第1步试运行测试集。利用Robot Framework的dryrun功能,虚拟地执行候选suite。所谓dryrun,就是在调用但不真正执行keyword的情况下,“尝试性”地执行测试。Robot Framework提供这个功能的本意是为了对测试代码进行快速的静态检查,发现语法问题。这里,RTS借用这个功能,得到与真实执行相同的,反映suite、test case和keyword调用关系的执行结果。

第2步:计算依赖关系。解析第1步的执行结果,使用递归算法获得每一个候选suite执行过程中直接和间接调用的keywords。当然,我们这里关心的是keyword所在的源文件路径。因此,我们计算得到的是每一个候选suite所依赖的包含keywords的Robot文件和Python文件列表。

第3步:选择测试子集。根据输入的改动文件列表文件和第2步得到的依赖性关系,从候选测试suite列表中过滤出所有依赖于至少一个改动文件的suite。过滤的结果就是选择的结果,其是候选测试suite列表的一个子集。

返回值:选择的suite子集。

以下图的例子说明RTS算法。图中有2个测试suite、2个robot资源文件和2个Python资源文件。图中的箭头代表文件之间的依赖关系:无箭头一端的文件依赖于箭头指向的文件。候选suite集合是。如果resource1.py文件发生变化,那么RTS计算得到的结果将是Suite1,即只有Suite1需要执行;如果Resource2.robot文件发生变化,那么RTS计算得到的结果是Suite2,即只有Suite2需要执行。

4. RTS算法分析

安全性:有些用例选择方法是根据上一次提交的执行结果来计算依赖性的。这种方法的弊端是,当前改动可能破坏旧的依赖性、构建新的依赖性,因而是不可靠的。RTS算法依靠Robot Framework的dryrun功能,完全不考虑历史依赖性,只关注包含当前改动的新的依赖性。只要Robot Framework的dryrun功能可靠,那么RTS算法的安全性就有保证。

效率:RTS算法的执行时间主要在于第1步和第2步。第1步取决于Robot Framework dryrun功能的效率。根据实际情况看,dryrun是非常快的,例如在数秒内能够完成几百个测试用例的执行。对于第2步,递归算法的效率主要取决于keyword的层级,而通常来说,keyword层级小于10层。因此,第2步的效率也是有保证的。

准确性:RTS无法完全保证准确性。这是因为RTS只能精确到文件级别,而通常的改动只是发生在文件的局部。因此,RTS容易将没有影响的suite误判为有影响。

另外,RTS算法在以下方面存在局限性,需要改进。

RTS不能处理Python文件之间的依赖性:RTS能够处理两个Robot文件之间的依赖,和一个Robot与一个Python文件之间的依赖,但是无法处理两个Python文件之间的依赖。这是因为,Robot Framework的dryrun功能只能获取Robot文件直接调用的Python keyword,对于Python keyword内部的调用则无法获取。对于这个局限,可以综合使用dryrun和Python依赖性分析工具(例如Snakefood)来打破。

RTS不能处理非Robot/Python文件的依赖性:对于测试用例来说,其有可能还依赖于一些静态文件,例如xml、txt、pem等。目前RTS还无法处理这种情况。未来可以通过直接解析robot/python文件来构建这种依赖性。

RTS不能识别case和keyword级别的依赖性:目前,RTS只能识别文件级别的依赖性。case和keyword都属于文件内部的模块,相互之间通常是严重耦合的,建立此类依赖性是一件有挑战的事情。

5. 总结

回归测试具有“价值高”和“成本高”的双重特点。依靠回归测试选择技术,可以在保持回归测试价值的前提下,显著降低回归测试的成本。回归测试选择技术需要满足安全、高效和准确三大要求。

本文针对Robot Framework提出了一种回归测试选择算法RTS,并对算法进行了分析。RTS能够实现一定程度上的自动化用例选择,但是也存在若干局限,有待持续完善。欢迎关注RTS的github地址:https://github.com/slxiao/rts, 一起参与对RTS的改进。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180602G1B3AQ00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券