Page 101 - 《软件学报》2025年第4期
P. 101

香佳宏 等: 大模型在软件缺陷检测与修复的应用发展综述                                                     1507


                 将对这些传统和基于学习的技术的代表性工作进行介绍, 指出各技术路线的发展目标和面临的挑战. 需要注意的
                 是, 在很多工作中, 为了增强工具性能或针对特定功能进行优化, 这些技术被结合使用以达到更优的效果.

                 4.1.1    传统的测试用例自动生成技术
                    基于搜索的测试用例自动生成技术将测试用例生成视为一个优化问题, 将覆盖率等评价指标作为优化目标,
                                                                        [6]
                 利用启发式搜索等算法求出使目标达到较优水平的测试用例. EvoSuite 是具有代表性的基于搜索的测试用例自
                 动生成技术, 该技术通过进化算法为给定的              Java 类自动生成测试用例. 具体来说, EvoSuite 采用基于搜索的方法,
                 集成了混合搜索和动态符号执行等技术, 并使用进化算法优化测试用例的覆盖率. 目前                           EvoSuite 已经通过插件的
                 形式集成到    Maven、IntelliJ 和  Eclipse 中, 并且被应用到一百多个开源软件和一些工业系统上, 发现了数千个潜在
                 的漏洞. 然而, EvoSuite 生成的测试与人工编写的测试在可读性上有较大差距, 导致在实际应用中开发人员并不愿
                 意采用   EvoSuite 自动生成的单元测试     [114] . 在面向对象程序中, 方法通常对复杂的类对象输入具有隐含的合法性要
                 求, 使得生成工具很难通过随机变异构造合法的类输入, 导致生成大量无效的测试用例. 为了应对这一问题, 在
                 EvoSuite 的基础上, Lin 等人开发了   EvoObj [115] . 通过结合静态分析技术, EvoObj 通过建立类对象构造图        (object con-
                 struction graph) 来表示焦点方法中的控制流和数据流信息, 并基于类对象构造图生成初始的测试用例提供给
                 等人提出了一个经典的基于约束的测试用例自动生成技术
                 EvoSuite. 相比于仅使用  EvoSuite, EvoObj 在  SF100  数据集  [116] 及其他  3  个开源  Java 项目上具有更优异的表现.
                    基于随机变异的测试用例自动生成技术由随机测试发展而来. 随机测试的变异过程缺乏启发式方法的指导,
                 导致其很难生成有效的测试用例. 在这种情况下, 研究人员开发了反馈驱动的随机测试生成算法, 该算法利用执行
                 已有测试用例时获得的反馈, 指导变异产生新的测试用例. Randoop 是一个经典的基于随机变异的测试用例自动
                                                                     [5]
                 生成技术. 在构建测试的过程中, Randoop        执行测试用例得到反馈, 并使用这些反馈信息指导搜索以产生新的、合
                 法的对象状态序列. 在这个过程中, Randoop         随机选择要调用的方法或构造函数, 使用先前计算出的值作为输入迭
                 代地构建测试. 因此, 该技术生成的测试通常由一系列创建和改变对象的方法调用, 以及对方法调用的结果的断言
                 组成. 通过将测试生成和测试执行相结合, Randoop           成为一种高效的测试生成技术, 在很多广泛使用的库中发现了
                 大量漏洞. 时至今日, Randoop    仍继续被工业界使用        [117] . 然而, 先前的反馈驱动的随机测试生成算法只能顺序地测
                 试焦点方法, 而无法为回调函数构造测试用例. 为解决这一问题, Selakovic 等人提出了                   LambdaTester [118] , 该工具通
                 过分析预测焦点方法参数的位置及相关信息, 以更好地生成测试用例. 在                       13  个  JavaScript 库中, LambdaTester 生
                 成测试用例的覆盖率均高于忽略焦点方法嵌套的随机生成工具, 且由复杂嵌套构成的测试用例在                                 12  个库中发现
                 了相关缺陷. 之后, Arteca 等人提出了      Nessie [119] , 该工具使用测试用例树  (test case tree) 作为测试用例的中间表达,
                 进而生成具有复杂调用嵌套的测试用例. 实验数据表明, Nessie 在测试用例的有效性和覆盖率表现都优于                             Lambda-
                 Tester.
                    基于约束的测试用例自动生成技术根据程序的约束条件指导生成测试用例. 对于程序来说, 约束指一系列分
                 支条件, 这些分支条件使程序沿一特定路径执行. 主流的基于约束的技术通常通过推断不变量                             (即程序执行某一部
                 分时, 部分变量恒满足的条件) 得到程序约束, 进而约束求解器可以直接根据程序约束生成测试. Daikon                          [120] 是一个
                 经典的基于约束的技术, 它首先运行初始的测试用例, 然后追踪程序运行时的数据, 并验证预设的不变量类型                                  (即
                 不变量模板) 是否符合数据行为, 从而推断测试用例运行过程中的不变量. 测试工具通过分析这些不变量, 进一步分
                 析出测试用例覆盖率不足的原因, 从而改进测试用例. 在许多相关工作中, Daikon 都被用作性能基准进行比较                          [116,121,122] .
                 在诸多基于约束的技术中, 研究者通过套用预先设置的不变量模板进行约束分析, 用户也可以根据自身需求加入
                 自定义的不变量模板. 然而, 在复杂程序中, 随着需要追踪的变量组合的迅速增长, 以及变量行为的复杂化, 不变量
                 推断的成本也呈指数级增长. 因此, 动态不变量推断系统通常只专注于一小部分简单的候选不变量. 基于此, Csallner
                                                              DySy [121] , 该技术结合动态符号执行技术进行不变量推
                 断, 从而更高效地捕捉不变量. 与过去技术不同, DySy            同时进行测试用例执行和动态符号执行, 进而采集程序的分
                 支条件构造不变量, 有效地改进了先前基于约束的工具.

                 4.1.2    基于学习的测试用例自动生成技术
                    虽然传统测试用例自动生成技术可以在一定程度上生成达到有效覆盖率的测试用例, 然而, 相较于开发者手
   96   97   98   99   100   101   102   103   104   105   106