Page 12 - 《软件学报》2026年第7期
P. 12

赵英全 等: 基于大语言模型的        Java 新特性测试程序生成                                           2697


                 序, 提升生成测试程序的复杂性和多样性            [23] .
                    目前, 随机差分测试已被广泛应用于编译器的测试工作中, 是编译器测试的主要方法之一. 比较经典的方法
                 为  Yang 等人  [6] 提出的针对  C  编译器的测试程序生成工具      Csmith. Csmith 中设计了大量  C  语言语法的生成规则, 例
                 如, 变量声明、控制流语句以及指针和数组等. 通过随机地组合这些语法规则, Csmith                       可以生成大量符合       C  语言
                 语法的测试程序, 并基于不同的          C  编译器实现   (例如  GCC、LLVM) 构造测试语言, 检测        C  编译器中潜在的缺陷.
                 由于  Java 程序往往存在复杂的内部依赖关系以及复杂的面向对象类型关系                      [28] , 现有针对  Java 的随机差分测试工
                                                    [5]
                 作相对较少. 具有代表性的工作为           JavaFuzzer . JavaFuzzer 在  Java 源程序的层面上设计代码生成规则, 通过生成
                 包含复杂循环结构、算术运算以及异常处理等结构的                   Java 测试程序, 对安卓虚拟机以及其他         JVM  实现进行测试.
                    不同于随机差分测试方法需要设计大量语法的生成规则, 程序合成方法则需要生成符合特定约束条件的测试
                 程序. 例如, 基于模板的测试程序合成方法            JAttack [26] , 其通过设计针对  JIT  编译器的测试程序模板, 程序模板中包
                 含使用领域特定语言        (domain specific language, DSL) 描述的待填充空白区域  (hole). 随后通过向模板中的空白区
                 域填充符合约束条件的代码片段, 生成多样的测试程序对                   JIT  编译器进行测试. 在此基础上, Zang      等人  [26] 进一步
                 提出了自动化的测试程序模板生成方法              LeJit, 其通过从已有的项目中提取       Java 程序, 并自动化地将程序中的表达
                 式转换为用    DSL  描述的空白区域, 构建更多样化的程序模板. 此外, 文献              [23–25] 提出了一系列基于历史揭错测试
                 程序的   JVM  测试程序合成方法. 具体来说, Zhao      等人  [23] 首先提出了  JVM  测试程序合成方法      JavaTailor, 其通过设
                 计  5  种代码片段衡量规则, 从历史揭错测试程序中提取所有符合规则的代码片段, 并将提取到的代码片段随机插
                 入至新的种子程序中, 从而生成新的测试程序. 然而, 不同的代码片段往往会存在相似的程序特征, 例如, 相似的控
                 制流. 因此, 在此基础上, Gao    等人  [24] 利用代码表示方法对代码片段进行向量化表示和聚类, 并采用基于反馈的代
                 码片段选择策略, 进一步提出了增强           JVM  测试效果的方法     VECT. 考虑到有限的历史揭错代码片段往往会限制测
                 试输入空间. 因此, Zhao    等人  [29] 提出了代码片段抽象到实例化的        JVM  测试程序生成方法       Jetris, 通过将代码片段
                 的控制流和数据流信息抽象为揭错模式, 并结合新的程序元素将揭错模式实例化为更多样的代码片段. 新生成的
                 代码片段将被插入至新的上下文中, 从而增强新生成测试程序的多样性, 拓展测试输入空间. 相关的研究工作还
                 有: 文献  [30,31] 通过引入外部知识或改进测试种子的构造方式来增强基于搜索的软件测试方法, 从而提升对复杂
                 程序结构和潜在缺陷的检测能力.
                    尽管现有的基于规约的测试程序方法已经取得较好的结果, 检测到了很多未知的                            JVM  缺陷. 然而, 现有方法
                 均不包含新特性的程序特征, 无法对新特性进行有效覆盖. 一方面, 现有随机差分测试方法所设计的代码生成规则
                 均为较基础的语法结构, 不包含新特性的语法结构, 且为所有的新特性实现相应的代码生成规则成本较高                                  [5,25] ; 另
                 一方面, 现有的基于程序合成的方法往往依赖于存在相应测试特征的种子程序, 例如, 历史揭错程序                              [23,24,26] . 然而,
                 新特性在发布时往往并不具备充足的历史揭错程序. 同时, 代码片段的分析和提取往往依赖程序分析工具, 在新特
                 性发布的初期, 同样没有程序分析工具的支持. 本方法利用大模型生成新特性代码片段很好地解决了需要针对性
                 设计代码生成规则的高成本问题, 利用程序分析工具分析历史揭错种子则避免了新特性对程序分析工具的依赖等
                 问题.
                  1.2   基于变异的测试程序生成
                    基于变异的测试程序生成方法通常在已有的种子程序上, 围绕编程语言的语法规则、语义约束以及编译器不
                 同的优化功能来设计相应的变异策略, 从而生成种子程序的变异体来检测潜在的编译器缺陷                              [9,11,32] . 具有代表性的
                 工作是   Le 等人  [9] 提出的等价取模输入    (equivalence modulo input, EMI) 方法, 该方法利用覆盖分析工具识别已有
                 测试程序中未被执行的代码语句. 随后, 通过随机删除未被执行的代码语句, 生成与原始种子程序在语义上等价的
                 变异体.
                    基于变异的     Java 测试程序生成方法在过去一段时间中得到了广泛的关注, 已成为提升                     Java 编译器与  JVM  正
                 确性的重要手段之一. 例如, Chaliasos 等人      [33] 提出的针对编译器类型系统的测试程序编译方法               Hephaestus, 其通
                 过基于类型擦除及类型重写设计的变异规则, 对种子程序进行变异. 生成的测试程序有效地检测出了                                Java 编译器
   7   8   9   10   11   12   13   14   15   16   17