1. 介绍
变更影响分析(change impact analysis)提供了对一系列程序变更的语义影响的反馈。
这篇文章针对面向对象编程语言进行分析,小的变更会有意想不到的结果:如,向现有类添加方法会影响整个程序虚拟方法的调用
本文的方法:
- 将源代码的变更映射到一组原子变更(使用类、方法、域和它们的相互关系作为变更的原子单元)
- 此外还确定了这些原子变更的偏序关系,这些变更间的偏序关系保证程序句法合法
- 给定一系列原子变更$\mathcal{A}$和给定的测试驱动集合$\mathcal{T}$,执行程序的部分功能
静态分析来确定:
- 测试驱动$\mathcal{T}$中挑选被变更$\mathcal{A}$影响子集$\mathcal{T’}$用于回归测试
- 变更集合$\mathcal{A}$的子集$\mathcal{A’}$可能影响$\mathcal{T}$中的某些测试驱动$\mathcal{t}$。这允许开发者忽略不被测试$\mathcal{t}$失败影响的变更
- 变更$\mathcal{A}$的子集可能不影响任何测试用例,这些变更可以立即纳入
- 覆盖率信息可以作为创建新测试用例的基础
2. 动机样例
贴了一页论文(-_-|||,太长不看)
该样例包含5个类:Course, Person, Professor, Student和University
然后有3个测试驱动:
- TestA:找到特定教授打印TA教授的课
- TestB:打印大学所有人员
- TestC:找到特定学生打印其学分
然后就是说了三个方面的对于代码的变更
3. 变更
规定源程序为$P$,修改后的程序为$\mathcal{P’}$,他们都语法正确且可编译。
3.1 原子变更
方法的一个关键是将源代码的编辑转换为一组原子变化
这些原子变更有两个重要特征:
- 粒度与分析内容相符合,也就是说,如果用了更细粒度的原子变更概念,分析也不会产生更精确的结果
- 任何源代码的编辑可以分解为唯一的原子变更集合
CM捕获对方法体的任意改变,包括:
- 在之前的抽象方法中添加方法体
- 从非抽象方法中删除方法体,让它抽象
- 方法体中任何语句级别的变更
LC类别对影响动态dispatch行为的源代码变更进行抽象,它可能由添加或删除方法,添加或删除集成关系导致。
change impact analysis 会忽略某些类型的源代码级别的变更,这些变更除了控制可见性外没有语义影响,如修改类/方法/域的修饰符,增删注释和增删import语句。
3.2 影响方法dispatch的变更
方法dispatch可能受多种编辑影响,我们使用$lookup$形式化方法dispatch过程。$lookup$ 接受两个参数:运行时类型和静态方法调用,返回通过virtual dispatch机制调用的方法定义
3.3 对原子变更排序
变更可能收到语法和语义上的其他变化。本文仅考虑必须满足的语法依赖性以保证可编译。语法依赖的例子有不能扩展未定义的类,或调用为定义的方法。语义依赖的例子是新增方法$m$仅在存在被调用的方法$m’$的改编版本时才表现出正确的行为。
使用原子变更上的偏序关系$\prec$表示语法依赖(同时也定义了传递闭包$\preceq^$),$\prec$定义了$\mathcal{A}$的consistent*子集$\mathcal{A’}$,使得$\mathcal{A’}$应用到$P$的结果是合法的程序$P’’$。
$\mathcal{A’}$是consistent满足的条件:
计算这些东西需要确定原子变更中引用的程序片段的语法要求
3.4 导出原子变更
将源代码编辑分解为原子变更是很简单直接的,文章由于篇幅原因只通过一个例子展示过程
4. 变更影响分析
程序$P$有一些列测试驱动$\mathcal{T}=t_1, \dots, t_n$,$Nodes(P, t_i)$表示程序$P$执行测试驱动$t_i$经过的方法结点,$Edges(P,t_i)$为调用关系。方法间的调用关系可以形式化地表示为:$A.m\rightarrow_CB.n$,表示$A.m$通过类型$C$对象的方法$n$调用了方法$B.m$
$\mathit{AffectedTests(\mathcal{T}, \mathcal{A})}$和$\mathit{AffectedChanges(\mathcal{t}, \mathcal{A})}$可以用来回归测试和故障定位,具体方法如下:
- 任何不在$\mathit{AffectedTests(\mathcal{T}, \mathcal{A})}$中的测试驱动在$\mathcal{A}$前后必定产生相同执行结果,所以只需要重新运行$\mathit{AffectedTests}$中受影响的测试驱动就行
- $\mathit{AffectedChanges(\mathcal{t}, \mathcal{A})}$可以识别没有影响任何测试驱动的改变,这些改变可以安全的包含(纳入)。有时候这样的改变也是暗示缺少了测试用例
- $\mathit{AffectedChanges(\mathcal{t}, \mathcal{A})}$可以在测试失败时提供有用的信息
7. 未来工作
- 从源代码编辑中导出原子变化
- 计算原子变更间的序