A Study of Regression Test Selection in Continuous Integration Environments

摘要

持续集成(CI)系统负责软件的自动化构建,测试执行和交付。CI提供了软件变更的快速反馈,最小化每次迭代需要的时间和成本。最近的工作主要通过RTS优化回归测试的开销。这些方法目标为CI环境,因为传统的RTS技术常常使用代码插装或十分细粒度的依赖分析,不能够处理快速地变更。本文中深度研究不同开源项目RTS在CI环境中的使用。本文分析了918个开源项目得到以下结论:

  1. 在什么条件下RTS是必要的
  2. 如何平衡RTS的分析粒度和精度

1. 绪论

有一个对423个开发者的调查,其中有70%开发者报告使用CI帮助他们更早地发现bug并让他们更少担心构建失败。与此同时,保证CI测试时快速的,应该运行“just-right”的测试用例集合

已有很多关于RTS方法的研究,但是他们很难适用于CI环境下。在CI场景下,测试请求可能来的很快,变更可能在RTS完成和运行前发生。举个例子,Hadoop 2.5.0每天迭代86个commit,给定16,837个方法和44,552个测试用例,不可能在方法级别跟踪所有的依赖进行分析计算

另一方面,粗粒度的技术算计来很快。举个例子,Google TAP经常使用粗粒度的依赖关系(比如模块级别)来进行快速的RTS,但是粗粒度的分析时不精确的。举个例子,Netflix依赖于Inter Process Communication library - Ribbon。若Ribbon代码变更了,Netflix和Ribbon的代码都要重跑。尽管粗粒度技术计算结果很快,但是它时间开销很大因为选择了很多与测试不相关的变更。因此要权衡考虑分析的粒度和结果的精度

我们的论文中,分析了918个使用CI的开源项目,分析7,018,512个commit。本文分析commit提交的频率和它们如何影响RTS的效率的。同时也分析commit间源代码文件改变的百分比以分析是否应该把时间花费在特定的文件上。此外,我们使用两种不同粒度的静态RTS技术,和ReTestAll作比较。

本文的主要贡献:

  1. 大部分commit(60%)发生在超过10分钟的时间间隔内,也就是说如果整个测试套件运行时间少于10分钟,那么RTS的在60%情况下式不需要的
  2. 对于间隔时间不超过10分钟的commit,代码修改主要集中在少部分(8.6%)的代码上
  3. 大部分(62.2%)的Java项目平均测试时间不超过平均commit间隔时间的25%,也就是说rts在整个开发周期中可能不必要
  4. 大多数(97.3%)的Java项目,方法级别的静态RTS比RetestAll效果差。在56.8%的Java项目中类级别的RTS比RetestAll节省时间

2. 背景和相关工作

A. 回归测试

给定程序P,P的修改版本P’,和P的测试套件T。回归测试的目的是为了验证P’的正确性。为了验证,开发者经常重跑T,但是重跑所有T的开销可能很大。所以常常使用通过RTS和优先级排序来提高回归测试效率

RTS技术尝试从T中选出一个子集T’,这些测试用例很重要需要重跑。已有研究显示当某些条件满足时,RTS是safe的,比如:它不能排除由于代码修改造成P’运行出错的测试用例。测试用例优先级(TCP,Test case prioritization)技术对测试用例进行排序时出错的测试用例尽早测试

B. Regression Test Selection

rts可以分为静态和静态技术。动态rts要求对程序插桩获取执行时信息,限制了在实践中的可用性。

相反,静态rts技术依赖于程序分析得到程序实体(语句,方法,类)间依赖图来了进行测试用例选择。当变更c发生时,所有c传递可达的实体,记为D,与D相关的测试用例都应该被选择。

QQ截图20190411090655.png
举个栗子,A-E表示方法,T表示测试用例。D、E属于同一个类文件C1,A、B、C属于同一个类文件C2。当使用方法级别的RTS时,当E改变了,只有T1被选择;若使用类级别的RTS,RTS会选择所有测试用例,因为C2依赖于C1。但是,类级别的依赖分析开销小于方法级别的依赖分析,尽管会选择更多的测试用例

进来也有很多回归测试相关的技术。Gligoric提出一种类级别的动态RTS技术,结果比细粒度的动态RTS效率更高,但是他们的工作关注动态RTS,在CI环境中往往有很大的运行时开销,不能用到实践中

Legunsen发现类级别的静态RTS比方法级别的静态RTS在22个java开源项目上效果更好,尽管他们是在开发环境上。

Elbaum提出使用时间窗口的RTS技术来跟踪最近测试用例如何执行和暴露错误。他们的技术是基于历史的,可能同时牺牲safety(丢失相关测试)和precision(选择不相关的测试)。

C. 持续集成

Hilton研究开源项目中CI的使用。Legunsen评估静态RTS技术和它们的safety的好处。Vasilescu研究CI在246个Github项目上的生产率(productivity)。但是这些研究只关注特定的RTS技术,没有说明什么RTS技术是需要的,也没说明哪些指标影响了大部分开源项目的RTS的开销和效率。

3. 研究问题

已有研究表明传统RTS不能直接用于CI环境应为它需要大量分析时间。当commit频率用来度量CI可扩展性时,RTS的可用性依赖于commit到达的时间和间隙。举个例子,如果短间隙的commit经常出现,那么就需要时间开销小的RTS。在某些开发阶段(当项目稳定时),commit发生在较长间隔内,就可以直接测试所有测试用例,然后就提出了以下研究问题:

  1. 不同项目的commit间隔怎样?
  2. 在不同时间间隔内修改了多少项目文件,他们和不同编程语言如何关联?
  3. 与RetestAll相比,RTS的哪种扩展在CI环境中更需要?
  4. 不同级别粒度的依赖分析哪个开销受益更大?

4. 实验设置

A. 收集数据集

# ProjectCC++JavaJavaScriptPythonPHPRubyScala
91860557721718312418022

5. 结果

A. 提交频率

表显示了commit数量和不同时间间隔的相关性

QQ截图20190411111412.png
RQ1结果:60%的commit发生在超过10分钟的间隔内,也就是说RTS的时间如果超过10分钟,那么RTS对大多数的项目是有帮助的。

B. 文件变更

RQ2结果:对于间隔的commit,变更只集中于其中一小部分(8.6%)的文件。这个结果说明依赖分析在RTS中可能是不必要的

C. 测试时间

RQ3结果:大部分(62.2%)的Java项目平均测试时间不超过平均commit间隔的25%。也就是说只有只需要对少部分的时间间隔比较小的commit进行RTS就可以了

D. 依赖分析

RQ4结果:类级别的依赖分析比方法级别的依赖分析表现更好,在43.2%的项目上可以减少的时间开销。在剩下56.8%的项目上,两种静态RTS方法没有减少时间开销

6. 讨论

7. 结论

本文对CI环境中的RTS进行了实证研究,分析了918个Github上的开源项目,分析了7,018,512个commit。研究问题包括commit频率,commit间项目文件如何改变,在什么情况下需要用到RTS技术和不同粒度的分析技术的区别。未来工作会扩展研究到更多对象程序上,并提出改进效率的RTS技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值