BERT: 一个行为回归测试工具

BERT: 一个行为回归测试工具

引用

Jin, Wei & Orso, Alessandro & Xie, Tao. (2010). BERT: A Tool for Behavioral Regression Testing. Proceedings of the ACM SIGSOFT Symposium on the Foundations of Software Engineering. 361-362. 10.1145/1882291.1882348.

摘要

在维护期间,软件被修改和发展以增强其功能,消除故障并使其适应已更改或新的平台。在本次展示中,我们将介绍 BERT,该工具可帮助开发人员识别在修改代码时可能引入的回归错误。 BERT 基于行为回归测试的概念:给定程序的两个版本,BERT 通过三个步骤通过动态分析来识别两个版本之间的行为差异。首先,它生成大量的测试输入,这些输入专注于代码的更改部分。其次,它在新旧版本的代码上运行生成的测试输入,并识别测试行为的差异。第三,分析发现的差异并将其呈现给开发人员。通过专注于代码的子集并利用差异行为,与传统的回归测试方法相比,BERT 可以为开发人员提供更详细的信息-这种方法完全依赖于现有的测试套件,其范围可能受到限制并且可能无法充分测试程序中的更改。 BERT 被实现为 Eclipse(一种流行的集成开发环境)的插件,并且可以免费获得。本次展示演示了 BERT,其基础技术及其用法示例。

关键字:回归测试,差异测试

BERT: 一个行为回归测试工具

图 1:方法的高层视图

1 技术和工具

与传统回归测试相比,图 1 提供了我们方法的高层视图。在传统的回归测试中,为程序的旧版本(V0)定义的现有测试套件(T0)将在程序的修改版本(V1)上运行。根据他们的所说,在 V1 上失败而在 V0 上没有失败的非过时测试用例将作为警告显示给开发人员,这可能表示存在回归错误。

自动化行为回归测试通过在两个主要方面改进回归测试来补充上述传统方法:(1)生成一组专门针对更改后的代码的测试输入;(2)它明确利用了旧的和新的代码版本。结果是这两个版本之间存在的一系列行为差异。此信息可以为开发人员提供有关其代码更改如何影响代码行为的更多和更细粒度的数据。行为上的意外更改以及有关这些更改的详细信息,可以帮助开发人员识别和消除回归错误。我们的技术的使用场景是该方法被集成到开发人员使用的 IDE 中,并在每次成功更新和编译代码时被激活。在这种情况下,代码中的更改量通常会受到限制和本地化。

BERT 当前是针对 Java 语言实现的,已集成到 Eclipse 中,并包括三个阶段:生成更改代码的测试输入,原始代码和更改代码的行为比较以及差异行为分析和报告。接下来,我们将概述这些阶段。有关这些阶段的完整详细信息,请参见描述此方法的论文。

阶段 1:生成更改代码的输入。

在阶段 1 的第一步中,BERT 通过利用变更分析器收集变更信息,变更分析器将所考虑程序的两个版本 V0 和 V1 作为输入,并生成两个版本不同的类的列表。为此,BERT 利用了 Eclipse 的两个功能:拦截事件以及在项目的两个版本之间生成更改信息的能力。更准确地说,BERT 会截获成功的编译事件,以便能够在每次修改,保存和编译项目的某些部分时执行其分析。当一个这样的事件触发时,BERT 使用 Eclipse 通过其 API 提供的功能比较项目的先前版本和新版本。此步骤的结果是项目中已修改类的列表。然后,BERT 通过将这些类别中的每个类别馈送到测试生成器,为 V1 中更改的类别生成一组测试输入。在该工具的当前版本中,我们使用 Randoop 和 JPF 作为测试输入生成器。我们之所以选择这些工具,是因为它们可以为单个类生成测试输入,并且只需进行最小的更改即可构建测试所需的支架(例如驱动程序和存根(即模拟对象))并生成易于运行的 JUnit 测试。

阶段 2:更改代码的行为比较。

在阶段 2 中,BERT 首先在其相应的类上运行阶段 1 中生成的所有测试。对于每个更改的类 c 和每个 c 的测试 t,测试运行器模块在 c 的旧版本和新版本 cv0 和 cv1 上运行 t。在由 t 执行的每次调用 m 的 c 方法之后,BERT 记录以下信息。首先,它记录由 t,instcv0 和 instcv1 创建和执行的 cv0 和 cv1 实例的状态。为此,它将在 instcv0 和 instcv1 中检索每个字段 f 的值,并将它们存储为元组:seqid 是唯一的(按版本)id,其值在第一次调用时为 1。对于每个后续呼叫增加;msig 是 m 的签名;name 是 f 的名称,value 是 f 的值。如果 f 是标量,则记录的值是 instcv0 和 instcv1 中 f 的实际值。如果 f 是对对象 o 的引用,则 BERT 递归记录每个 o 字段的值,直到遇到标量字段或达到用户定义的深度为止。其次,BERT 在两种情况下将 m 返回的返回值存储为元组,其中 seqid,msig 和 value 的定义与前一种情况相同。如果该方法以异常终止,则将异常的值存储为返回值。第三,BERT 捕获通过执行 m 产生的输出,并将其存储为的形式,其中 seqid 和 msig 具有通常的含义,destination 是发送输出的实体(例如 a 文本终端,网络端口,图形元素),数据是发送给该实体的原始数据。最后,在调用 m 之后记录每个值,BERT 还会在 t 引起的动态调用图中记录 m 和任何更改的方法之间的最短距离,该距离随后用于对差异进行排名。为了记录此信息,BERT 使用 Javassist 对测试和被测代码进行检测(http://www.csg.is.titech.ac.jp/~chiba/ javassist),它是一种用 Java 编写的字节码重写库。

​ 当 t 的执行终止并生成数据日志时,BERT 的行为比较器将访问 instcv0 和 instcv1 的日志,并比较状态、相应调用的返回值以及为该类的两个版本收集的输出。对于发现的每个差异,BERT 都会记录一个事实,即存在差异,并且针对该类型的差异记录了一组相关数据。特别得,每个记录的更改都用一个唯一的 t 标识符标记,这可以将单个更改映射到显示它们的测试中。对所有更改的类执行阶段 1 中生成的所有测试后,结果是每个类的一组零个或多个原始行为差异。 每个行为差异都由状态、返回值或输出差异及其上下文信息组成。

阶段 3:差异行为分析/报告。

​ 第 3 阶段分析并操纵在上一个阶段中产生的差异集,以对它们进行分组和排序,使得开发人员可以更好地利用 BERT 产生的信息。为了实现这一目标,BERT 的行为差异分析器首先根据它们代表回归错误的可能性对它们进行排名或过滤。然后,它提取掉原始差异中包含的某些信息,并减少已识别差异集内的冗余。首先,BERT 根据其距离值将差异集划分为多个类别,以使具有相同距离的差异属于同一类别。然后,它对一个类中涉及相同实体的更改进行分组。例如,对于与状态相关的差异,分析器将涉及同一方法和字段的所有差异归为单个行为差异,将其与揭示每个个体差异的一组测试输入相关联,并分别存储各个值差异进一步分析。

此阶段的总体结果是 cv0 和 cv1 之间的一组行为差异,其中包括(1)哪些字段可以具有不同的值,(2)哪些方法可以返回不同的值,以及(3)哪些输出可能在 cv0 中发生差异 和 cv1,以及哪些测试输入会引起这种差异。 BERT 在 Eclipse 自定义视图中向开发人员报告这些差异,并按与他们的距离值成反比的顺序排列(即差异在排列顶部的距离更大)。BERT 还可以基于报告总数过滤掉给定距离以下的报告。这种排名和过滤背后的直觉和基本原理是,与实际变化相距较远的行为差异比故意发生变化的行为差异更不可能是故意的,这一直觉已由我们的经验评估结果证实。

开发人员可以使用此信息来评估哪些差异可能表明存在回归错误,以及在代码上执行了更改后会有哪些预期的差异。如果开发人员确定了回归错误,则他们可以使用与相应行为差异相关的测试输入来重现和调查错误行为,并最终消除错误。

2 与现有工具的关系

据我们所知,我们的行为回归测试方法是新颖的,并且 BERT 是第一个实现该方法的工具。大多数回归测试技术和工具将和 BERT 的相互补充,而非可以替代 BERT。特别得,可以将测试输入生成和维护工具(如 Parasoft Jtest)与 BERT 集成在一起,以改善其测试生成和执行阶段。同样,可以从系统测试中生成单元测试用例的捕获和重播工具可以与 BERT 结合使用,以扩展用于测试变更的单元测试集。

3 BERT 的好处

BERT 具有两个关键方面,使其有别于传统回归测试。首先,它专注于代码的一小部分,这使它可以生成更全面的测试集。其次,它利用差异行为,消除了对开发人员需要耗费大量脑经解决问题的需求。由于这些新颖的方面,与传统的回归测试方法相比,BERT 可以为开发人员提供更多(更详细)的信息。 我们对 BERT 的评估提供了这种用途的初步证据:对于所考虑的案例,BERT 能够识别出真正的回归错误,同时生成可以通过排名而减少的误报。该演示演示了 BERT,并在实践中展示了这样的结果和好处。

致谢

本文由南京大学软件学院 2020 级硕士生唐昊杰翻译转述 感谢国家重点研发计划(2018YFB1003900)和国家自然科学基金(61832009,61932012)支持!


分享到:


相關文章: