摘要
回归测试用例选择(Regression Test Selection, RTS)通过选择和重跑受代码变更测试来减少回归测试开销
文件级别的RTS(FRTS)相比更细粒度的技术(方法级别),开销更小
本文的HyRTS方法结合了方法粒度和文件粒度
实验在32个项目的2707个版本,共计124百万行源码上进行实验
1. 绪论
减少回归测试开销的方法:
- 回归测试用例选择
- 回归测试用例约减
- 回归测试用例优先级排序
典型的RTS技术需要两方面的信息:
- 测试依赖信息(测试在执行时可能执行到的程序元素)
- 改变的程序中的元素
safe的RTS技术会覆盖所有收到影响的测试
RTS技术分类:
根据测试依赖收集方法分:
- 动态方法
- 静态方法
根据变更分析的粒度:
- 基本块级别
- 方法级别
- 文件级别
- 模块级别
细粒度的RTS有更少的end-to-end时间(包含RTS时间和实际测试时间)
文件级别的RTS会比细粒度的RTS选出更多的测试用例,大概两倍
2. 背景和例子
文件级别的开销更小,有以下几个方面的原因:
- 收集依赖时,文件级别比方法级别更快
- 文件级别的变更可以根据文件的checksums获取
- 文件级别的RTS不需要跟踪动态的变更
例子就不写了。。
3 技术和实现
3.1 基础HyRTS
- 文件级别的分析通过文件变更选择所有受影响的测试用例
- 方法级别分析通过方法级别变更挑选受影响的测试用例
- 执行期间收集测试依赖用于之后的RTS
- 收集阶段收集到的依赖时方法级别的
- 在下一个软件版本,方法级别的依赖直接用于方法级别分析
- 文件级别的依赖可以从方法级别的依赖中提取出来
3.1.1 变更计算
通过checksums检测文件是否改变,通过smart checksums计算二进制文件是否变更
具体的算法如上。Lines 5-9, 对于未变更文件,文件中的所有方法级别的checksums直接保存。在文件变更计算时(Line 11),HyRTS计算Table 2中的头四种类型的变更。头三种变更是文件级别的,CF是方法级别的,通过Line 13计算方法级别的变更。
域变更(field changes)不被跟踪,因为所有域变更都会反映到相关方法级别的变更。
3.1.2 依赖收集
通过JVM加载时代码插装进行跟踪。重写了ClassVisitor
和MethodVisitor
记录方法的依赖信息
本工具进行测试类级别的测试用例选择,因为测试方法在实践中很难隔离
HyRTS用到的所有测试依赖表示为$\mathbb{TD}=\{\mathcal{TD_m}, \mathcal{TD_f}\}$,$\mathcal{TD_m}$表示方法级别的测试依赖,$\mathcal{TD_f}$表示方法级别的测试依赖
$\mathcal{TD_m}$只在运行时收集,$\mathcal{TD_f}$在离线时从$\mathcal{TD_m}$中导出
3.1.3 RTS和应用模式
$\Delta$表示变更信息
$\mathbb{TD}$表示测试依赖
那么当前版本需要选择的测试用例为之前版本依赖上被变更覆盖的测试:
4. 实验
4.2 实验对象
32个项目的2707个版本,共计124百万行代码
4.3 实验设置
RTS度量:
- 选择测试用例比例
- 端到端的测试时间:从测试用例选择到执行结束
5. 结果分析
HyRTS选择18.35%测试用例,时间开销31.60s;FRTS选择27.18%测试用例,时间开销40.06s
6. 相关工作
- 动态RTS
- 静态RTS
7. 结论
引入更细粒度的基本块级别的分析不会减少时间开销,把实例方法增删转变为文件级别的改变的HyRTS变体,相比于FRTS可以显著提升测试的效率