Change Impact Analysis for Object-Oriented Programs

1. 介绍

变更影响分析(change impact analysis)提供了对一系列程序变更的语义影响的反馈。

这篇文章针对面向对象编程语言进行分析,小的变更会有意想不到的结果:如,向现有类添加方法会影响整个程序虚拟方法的调用

本文的方法:

  1. 将源代码的变更映射到一组原子变更(使用类、方法、域和它们的相互关系作为变更的原子单元)
  2. 此外还确定了这些原子变更的偏序关系,这些变更间的偏序关系保证程序句法合法
  3. 给定一系列原子变更 A \mathcal{A} A和给定的测试驱动集合 T \mathcal{T} T,执行程序的部分功能

静态分析来确定:

  • 测试驱动 T \mathcal{T} T中挑选被变更 A \mathcal{A} A影响子集 T ′ \mathcal{T'} T用于回归测试
  • 变更集合 A \mathcal{A} A的子集 A ′ \mathcal{A'} A可能影响 T \mathcal{T} T中的某些测试驱动 t \mathcal{t} t。这允许开发者忽略不被测试 t \mathcal{t} t失败影响的变更
  • 变更 A \mathcal{A} A的子集可能不影响任何测试用例,这些变更可以立即纳入
  • 覆盖率信息可以作为创建新测试用例的基础

2. 动机样例

贴了一页论文(-_-|||,太长不看)

该样例包含5个类:Course, Person, Professor, Student和University

然后有3个测试驱动:

  • TestA:找到特定教授打印TA教授的课
  • TestB:打印大学所有人员
  • TestC:找到特定学生打印其学分

然后就是说了三个方面的对于代码的变更

3. 变更

规定源程序为 P P P,修改后的程序为 P ′ \mathcal{P'} P,他们都语法正确且可编译。

3.1 原子变更

方法的一个关键是将源代码的编辑转换为一组原子变化

QQ截图20181225150436.png

这些原子变更有两个重要特征:

  1. 粒度与分析内容相符合,也就是说,如果用了更细粒度的原子变更概念,分析也不会产生更精确的结果
  2. 任何源代码的编辑可以分解为唯一的原子变更集合

CM捕获对方法体的任意改变,包括:

  1. 在之前的抽象方法中添加方法体
  2. 从非抽象方法中删除方法体,让它抽象
  3. 方法体中任何语句级别的变更

LC类别对影响动态dispatch行为的源代码变更进行抽象,它可能由添加或删除方法,添加或删除集成关系导致。

change impact analysis 会忽略某些类型的源代码级别的变更,这些变更除了控制可见性外没有语义影响,如修改类/方法/域的修饰符,增删注释和增删import语句。

3.2 影响方法dispatch的变更

方法dispatch可能受多种编辑影响,我们使用 l o o k u p lookup lookup形式化方法dispatch过程。 l o o k u p lookup lookup 接受两个参数:运行时类型和静态方法调用,返回通过virtual dispatch机制调用的方法定义

3.3 对原子变更排序

变更可能收到语法和语义上的其他变化。本文仅考虑必须满足的语法依赖性以保证可编译。语法依赖的例子有不能扩展未定义的类,或调用为定义的方法。语义依赖的例子是新增方法 m m m仅在存在被调用的方法 m ′ m' m的改编版本时才表现出正确的行为。

使用原子变更上的偏序关系 ≺ \prec 表示语法依赖(同时也定义了传递闭包 ⪯ ∗ \preceq^* ), ≺ \prec 定义了 A \mathcal{A} Aconsistent子集 A ′ \mathcal{A'} A,使得 A ′ \mathcal{A'} A应用到 P P P的结果是合法的程序 P ′ ′ P'' P

A ′ \mathcal{A'} A是consistent满足的条件:
∀ a ′ ∈ A  such that  a ′ ⪯ ∗ a , a ∈ A ′ ⇒ a ′ ∈ A ′ \forall a'\in A\text{ such that }a'\preceq^*a, a\in A'\Rightarrow a'\in A' aA such that aa,aAaA
计算这些东西需要确定原子变更中引用的程序片段的语法要求

3.4 导出原子变更

将源代码编辑分解为原子变更是很简单直接的,文章由于篇幅原因只通过一个例子展示过程

4. 变更影响分析

程序 P P P有一些列测试驱动 T = t 1 , … , t n \mathcal{T}=t_1, \dots, t_n T=t1,,tn N o d e s ( P , t i ) Nodes(P, t_i) Nodes(P,ti)表示程序 P P P执行测试驱动 t i t_i ti经过的方法结点, E d g e s ( P , t i ) Edges(P,t_i) Edges(P,ti)为调用关系。方法间的调用关系可以形式化地表示为: A . m → C B . n A.m\rightarrow_CB.n A.mCB.n,表示 A . m A.m A.m通过类型 C C C对象的方法 n n n调用了方法 B . m B.m B.m

QQ截图20181225165339.png

A f f e c t e d T e s t s ( T , A ) \mathit{AffectedTests(\mathcal{T}, \mathcal{A})} AffectedTests(T,A) A f f e c t e d C h a n g e s ( t , A ) \mathit{AffectedChanges(\mathcal{t}, \mathcal{A})} AffectedChanges(t,A)可以用来回归测试和故障定位,具体方法如下:

  • 任何不在 A f f e c t e d T e s t s ( T , A ) \mathit{AffectedTests(\mathcal{T}, \mathcal{A})} AffectedTests(T,A)中的测试驱动在 A \mathcal{A} A前后必定产生相同执行结果,所以只需要重新运行 A f f e c t e d T e s t s \mathit{AffectedTests} AffectedTests中受影响的测试驱动就行
  • A f f e c t e d C h a n g e s ( t , A ) \mathit{AffectedChanges(\mathcal{t}, \mathcal{A})} AffectedChanges(t,A)可以识别没有影响任何测试驱动的改变,这些改变可以安全的包含(纳入)。有时候这样的改变也是暗示缺少了测试用例
  • A f f e c t e d C h a n g e s ( t , A ) \mathit{AffectedChanges(\mathcal{t}, \mathcal{A})} AffectedChanges(t,A)可以在测试失败时提供有用的信息

7. 未来工作

  1. 从源代码编辑中导出原子变化
  2. 计算原子变更间的序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值