Page 113 - 《软件学报》2025年第7期
P. 113

3034                                                       软件学报  2025  年第  36  卷第  7  期


                 归测试用例. 另一方面, 如果测试套件能够覆盖到缺陷相关的源码但是缺少触发缺陷的关键因素, 那么开发者将会
                 通过修改已有的测试用例使其能触发该缺陷作为回归测试用例, 以期最小程度地修改测试套件. 因此, 研究回归测
                 试用例修改程度有助于理解触发缺陷测试用例和已有测试套件的关联程度.
                    由于存在一些修复缺陷的          PR  并不包含相应的回归测试用例, 或者回归测试用例并没有与修复缺陷的补丁在
                 同一  PR  中提交且缺少关联. 为此, 本文分析仅与缺陷补丁同时提交的                  286  个回归测试用例. 具体来说, 本文首先
                 判断回归测试用例属于新增的还是基于已有测试套件修改的. 接着, 对于基于修改的测试用例, 本文进一步统计了
                 回归测试用例涉及的变更行数, 变更行数等于删除行数与新增行数的总和. 需要注意的是, 如果将一行代码中部分
                 内容做了修改, 则等价于将原始错误的代码行删除, 并新增一行正确的代码. 统计结果显示, 在研究的                              286  个回归
                 测试用例中, 170   个是完全新增的, 116     个是基于已有的测试用例修改而成的. 完全新增的回归测试用例占比高达
                 59.44%, 这表明  DL  编译器中存在较多的功能点没有被开发人员手写的测试套件覆盖到. 因此, 使用源码覆盖指导
                 的测试用例生成方法是一种潜在有效的缺陷检测方法. 并且已有的测试技术                         (比如, HirGen、NNSmith) 都没有使
                 用源码覆盖来指导测试用例生成.
                    除此之外, 本文进一步统计了         116  个基于修改的回归测试用例的修改行数, 其修改行数分布如表                   6  所示. 从表
                 可知, 50%  基于修改的回归测试用例涉及的修改行数小于               10  行. 由于该代码修改行数可能是对多个测试用例同时
                 做的修改. 因此, 通常情况下触发缺陷的测试用例仅需要修改其中一个测试用例即可. 也就是说, 多数情况下, 设计
                 变异算子对测试套件进行轻微修改即可触发此类缺陷. 因此, 使用开发者手写的测试套件作为种子, 并设计针对
                 DL  编译器缺陷的变异算子是另外一种潜在可行的缺陷检测方法.

                                                  表 6 测试用例修改的行数

                                            测试用例修改行数               对应缺陷数量
                                                [1, 5]                 42
                                                [6, 10]                16
                                                [11, 15]                9
                                                [16, 20]               11
                                                [21, 25]                5
                                               [26, +∞]                33

                    发现  11. 59.44%  的回归测试用例是完全新增的, 表明提升源码覆盖能力是设计                  DL  编译器缺陷检测方法的一
                 个重要指导方案. 同时, 50%      的修改回归测试用例涉及不到           10  行代码变动, 暗示通过变异已有测试套件生成新的
                 测试用例是另一种可行的缺陷检测方案.

                 4.6   RQ6: 补丁大小
                    研究补丁的大小对指导程序的规范化开发和缺陷的自动化修复有较好的指导作用. 为此, 本文从修复缺陷的
                 PR  中收集每个缺陷对应补丁所涉及函数的个数. 具体来说, 我们使用了                    libClang [43] 和基于模板的解析规则对代码
                 变更所涉及的源码文件进行解析以获取源码文件中的函数分布情况, 即每个函数在文件中的起始行与结束行. 接
                 着, 通过行号与相应文件的函数分布进行比对获取每个缺陷修复所使用的补丁中修改的函数数量. 需要注意的是,
                 这种自动解析方法无法处理一个            PR  中包含多个缺陷修复的补丁. 因此, 本文通过人工分析的方式以区分一个                     PR
                 中修复不同缺陷的补丁.
                    补丁所涉及的函数数量的分布如表             7  所示. 由表可知, 78.30% 的缺陷修复补丁涉及的函数数量在            3  个及以下.
                 具体来说, 修改了一个函数的补丁占补丁总数目的                 46.82%, 所占的比例最高, 而修改了       2  个函数和  3  个函数的补
                 丁数目则分别占      15.33% 和  7.34%. 另外, 补丁涉及函数的个数为      0  的缺陷中, 38.89%  的缺陷根因为配置问题. 这
                 表明补丁不会做出过于复杂的修改, 一般来说补丁只涉及较少部分的修改, 这也与传统软件的缺陷特征相同. 此
                 外, 对于不同的    DL  编译器, 修复缺陷的补丁大小分布也有所不同, 具体来说, 在                AKG 与  Glow 中补丁涉及的函数
                 个数小于或等于      4  的比例较高, 分别达到     35.87% 和  29.76%. 本工作对这些补丁进行了分析, 发现它们往往会在多
                 个不同的函数中进行逻辑相似的修改, 因此尽管这类补丁修改的函数数量较多, 却大多为可以避免的冗余修改. 这
   108   109   110   111   112   113   114   115   116   117   118