首页> 中国专利> 一种基于测试用例构建决策树的程序条件语句自动化修复系统及方法

一种基于测试用例构建决策树的程序条件语句自动化修复系统及方法

摘要

本发明涉及一种基于测试用例构建决策树的程序条件语句自动化修复系统及方法,针对程序的条件语句,从测试用例集的执行信息产生用于训练的数据集,引入决策树进行监督学习的方法产生补丁代码进行修复,并且利用一定的搜索策略克服了错误的条件语句多次执行的困难。通过本发明进行自动化修复,可达到较高的修复成功率和较快的执行效率,同时学习训练和生成补丁的核心模块具有很高的通用性和鲁棒性,能够适用于多种程序语言和环境。

著录项

  • 公开/公告号CN107577603A

    专利类型发明专利

  • 公开/公告日2018-01-12

    原文格式PDF

  • 申请/专利权人 中国科学院软件研究所;

    申请/专利号CN201710769700.0

  • 发明设计人 刘誉臻;张震宇;

    申请日2017-08-31

  • 分类号

  • 代理机构北京科迪生专利代理有限责任公司;

  • 代理人安丽

  • 地址 100190 北京市海淀区中关村南四街4号

  • 入库时间 2023-06-19 04:15:03

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2019-11-12

    授权

    授权

  • 2018-02-06

    实质审查的生效 IPC(主分类):G06F11/36 申请日:20170831

    实质审查的生效

  • 2018-01-12

    公开

    公开

说明书

技术领域

本发明涉及一种基于测试用例构建决策树的程序条件语句自动化修复系统及方法,属于软件测试与调试技术领域。

背景技术

软件测试和调试是保证软件质量的重要环节,也是最耗时和最困难的工作之一。对程序进行自动化的测试能够有效提高软件开发效率和质量,而对程序做自动化修复能够在非常节约人力成本的情况下让程序错误得到最大限度及时有效的修正。因此研究人员开始关注并提出了很多自动化生成补丁修复程序的思路与方法。

程序的自动化修复可以从很多角度展开,例如可以在源代码级别或者中间代码甚至可执行代码级别,相应的也有静态的修复和动态运行时进行修复,有针对特定类型错误的也有面向通用程序和通用错误的。目前较常用的分类是基于约束的程序修复与基于测试用例集的程序修复,本发明提出的方法属于后者。基于测试用例的修复首要目标是在发现有失败测试用例即发现了程序错误之后,对源代码进行修改以使测试用例全部通过。其基本假设是测试用例相对足够充分,且测试用例的产生遵循了一定的规则例如等价类划分、边界值、分支覆盖等,这样一套完善的测试用例集足够将程序的预期行为都覆盖到并且做出隐含的描述,因此通过了全部测试用例可以认为等价于在各种输入下都可正常执行。

目前基于测试用例的自动化修复主要有基于搜索的方法、基于语义分析和约束求解的方法以及基于先验知识和特征的方法等。这些方法仍往往面临一些困难,例如搜索空间巨大和条件组合爆炸问题、约束求解器的性能和功能的限制以及修复方法的鲁棒性和通用性问题等。

发明内容

本发明技术解决问题:克服现有技术的不足,提供一种基于测试用例构建决策树的程序条件语句自动化修复系统及方法,通过本发明进行自动化修复,可达到较高的修复成功率和较快的执行效率,同时学习训练和生成补丁的核心模块具有很高的通用性和鲁棒性,能够适用于多种程序语言和环境。

本发明技术解决方案:一种基于测试用例构建决策树的程序条件语句自动化修复系统,全自动的进行错误定位修复和验证无需人工干预,无需任何先验知识和人的经验完全基于测试用例集的数据进行学习,对条件语句进行翻转来获得执行并获得训练数据集,利用决策树进行训练并产生修复代码,利用决策树的剪枝和训练集搜索过滤算法。

所述系统包括:可疑条件语句定位模块,程序预处理模块,训练数据收集模块,模型学习和补丁生成模块,补丁验证和回归测试模块;其中:

可疑条件语句定位模块:根据测试用例集,利用程序插桩工具,运用基于程序覆盖的错误自动定位技术针对程序源代码中的条件语句按照可疑度由高到低进行排序,顺次作为可疑条件语句输入后续模块;

程序预处理模块:对给定的可疑条件语句所在行,对条件表达式布尔值进行翻转获得程序原版本和变异版本程序,并收集在两个版本程序,即程序原版本和变异版本程序的当前位置中可访问到的程序变量列表,程序变量列表包括静态变量,全局变量,局部变量,常数定义和函数参数;利用插桩工具插入获取这些变量运行时状态和条件表达式结果值的语句,得到插桩后的两个版本程序源代码供训练数据收集模块产生训练数据集;

训练数据收集模块:对程序预处理模块中所述两个版本程序分别执行测试用例集,收集每个变量在两个版本程序中执行每个测试用例的运行时值计入日志,过滤选取每个测试用例在两个版本中仅有一个为成功另一为失败的用例,并收集这些用例下两版本程序中成功的一方所打印出的变量值作为训练数据集;

模型学习和补丁生成模块:将训练数据集中每个用例下的每个变量值作为不同的输入维组成一个输入向量,将每个用例下条件表达式的值作为输出值,对训练集进行基于决策树的二分类监督学习,可生成一颗二叉树结构的分类器,并解析这棵树生成补丁语句;

补丁验证和回归测试模块:将生成的补丁语句应用到原程序中并运行整个测试用例集,如果全部通过则结束并成功进行修复,否则筛选训练数据集中的训练数据项以及限制决策树深度进行再次尝试直到成功修复或最终失败。

本发明的一种基于测试用例构建决策树的程序条件语句自动化修复方法,实现步骤如下:

(1)对C程序使用编译程序进行编译,使可执行程序中带有记录源代码中每条语句的执行次数的覆盖信息,执行完全部测试用例集之后可收集到每行被成功和失败用例分别执行的次数,利用可疑度计算公式如Tarantula计算每行可疑度并按行进行排序;

(2)利用词法和语法分析工具将该条件表达式取反即其结果做一次翻转产生一个变异版本,再使用程序静态分析工具获得指定语句上可访问到的变量列表,并插入输出语句将运行时这些变量在这一点的值作为一个输入向量,以及条件表达式的结果值作为输出,这样每个测试用例将执行这个条件语句零至多次,每次执行将产生一个分类训练的样本,原版本和对应变异版本产生的同一条训练样本,只有输出不同;

(3)执行两个版本程序的被测程序,分别得到两份变量运行时状态收集日志,对于每个测试用例在两份日志中可能存在多条训练样本,选取两个版本中只有其中之一为成功另外一个为失败的用例所对应的那份日志中该用例的全部训练样本,这样的全部训练样本合在一起作为学习分类器的最终训练数据集;

(4)使用决策树算法在收集到的训练数据集上进行训练,如果生成的决策树深度超过阈值则认为发生过拟合,进一步对训练集进行筛选,过滤掉在单个测试用例中可疑条件语句执行次数超过某阈值的用例所对应的训练样本,并对生成决策树的最大深度做出限制,多次修改阈值参数反复进行训练直到得出满足要求的分类器,并将该决策树解析为一个布尔表达式,或者未找到该分类器则对该可疑条件语句修复失败,回到程序预处理模块采用下一可疑条件语句尝试修复;

(5)将模型学习和补丁生成模块产生的布尔表达式作为可疑条件语句的补丁替换原有表达式,执行回归测试,如果修改后的程序通过全部测试用例则修复成功,否则回到模型学习和补丁生成模块继续调整参数进行训练。

本发明与现有技术相比的优点在于:

(1)准确度高:由于基于测试用例集的程序自动化修复所追求的的目标为让全部测试用例通过,而决策树的学习算法通常具有的过拟合的缺点此时恰好转化为提升准确率的优势,同时通过筛选训练集的阈值调整和补丁验证可将拟合程度控制在恰好的状态,保证了修复结果的通用性和准确性;

(2)语义清晰:由于决策树的分类器结构逻辑上完全等效于条件语句的判断过程,因为通过决策树来构建条件语句的补丁代码具有很强的可读性和可解释性;而且合理产生的测试用例的输入能很好地反应不同情况下的输入边界,决策树可以很好地将其挖掘出来;

(3)快速:针对条件语句的修复搜要搜索的可疑语句比通常少一个数量级,能有效加快错误定位的速度;同时对指定的语句利用收集好的训练集去学习获得分类器再转化为补丁代码,避免了盲目生成补丁再反复运行测试用例去验证的最耗时的步骤,速度提升非常明显;

(4)鲁棒性强:利用数据和监督学习生成决策树的模块是该方法的核心,这将对程序的分析从不同的程序语言、运行平台等隔离出来,仅需对其他部分做少量适配即可实现不同语言平台的自动化修复,具有很强的可移植性和鲁棒性;

(5)轻量级:避免进行复杂的程序静态分析和形式化方法及约束求解等较繁琐的操作,也无需对目标空间进行穷举的搜索,仅需少量程序预处理工作就可接入到通用的模型学习和补丁生成模块,环境配置简单轻量。

附图说明

图1为本发明系统的体系结构图;

图2为本发明中可疑条件语句定位模块结构图;

图3本发明中程序预处理模块结构图;

图4本发明中训练数据收集模块结构图;

图5本发明中模型学习和补丁生成模块结构图;

图6本发明中补丁验证和回归测试模块结构图。

具体实施方式

下面结合附图对本发明进行详细说明。

如图1所示,本发明的方法是一种基于测试用例集的对条件语句进行自动化修复的方法,所需输入包括存在条件语句错误的被测程序和对应的测试用例集,在无需其他人工设置和干预的情况下,自动化的定位错误行并且利用决策树监督学习得到可行的补丁代码。更具体地包括以下几个模块:可疑条件定位模块、程序预处理模块、训练数据收集模块、模型学习和补丁生成模块以及补丁验证和回归测试模块等。

(1)对被测程序运行测试用例时,会有通过的用例和失败的用例,而不同用例的运行时对源代码中每行语句的覆盖情况也不相同。通常在通过的测试用例中执行到某一错误语句的概率较小而失败用例更可能因为覆盖到了错误语句而导致失败。而其他语句在成功与失败用例间的覆盖情况未必存在明显的区别。因此可以根据某一行失败用例覆盖数、失败用例未覆盖数、通过用例覆盖数和通过用例未覆盖数组成四元组来计算其是错误语句的可疑度,并按行可疑度排序,作为自动定位的错误推荐列表。每次按顺序输出一行指定为错误语句输出到程序预处理模块尝试修复。

(2)从可疑条件语句定位模块获取到可疑语句后,为了获得错误的条件语句的期望输出,将给定行条件表达式取反得到两个版本的程序代码。并收集在该行位置时能够访问到的程序所有程序变量,包括局部变量、全局变量、函数参数、静态变量等。在该行位置前插入输出语句将这些变量的值以及可疑的条件表达式的值记录在日志文件中,这样在运行每个测试用例时每执行到该行一次会得到一个由可访问变量组成的向量,对应还有其布尔的输出值。将插桩后的原版本和变异版本的程序输入到训练数据收集模块。

(3)将两个版本的程序源代码分别运行全部测试用例,针对某一用例可能会有四种情况:两个版本都通过、都失败、原版本通过编译版本失败和原版本失败编译版本通过。从产生的记录变量运行时值的日志文件中,选取属于后两种情况的用例下的记录作为训练集,且仅选取两个版本中仅选取通过的版本,丢一另一版本的数据。将训练数据集作为模型学习和补丁生成模块的输入。

(4)将获得到的训练数据,不用分割数据集为训练集和测试集,直接利用决策树算法进行监督学习。如果条件语句只在每个用例下执行一次,即没有循环或者多个调用,则收集到的条件表达式的值可视作期望输出,任意产生该输出的表达式能够确保该用例通过。因此即使存在过拟合,得到的分类器也恰好可以将测试用例集中的全部用例做出正确输出进而完成修复。如果可疑条件表达式处在循环中被执行多次,则无法保证收集阶段得到的表达式输出是期望输出,即训练集中引入了噪声数据。需要对数据集根据每个用例中执行该条件语句循环的次数作为限制指标进行过滤,只选取循环1次,2次等的向量加入训练集再进行学习。最后将得到的分类器解析为条件表达式输出到补丁验证和回归测试模块。

(5)模型学习和补丁生成模块得到的补丁并不确保正确,因此需要进行验证。将测试用例集全部用例执行一次,如果全部通过则达到目标输出该补丁,如果有用例仍未通过则返回到模型学习和补丁生成模块,按照规则调整参数后继续学习得到候选补丁代码。

上述实现过程具体实施如下:

1.可疑条件语句定位模块

该模块的实现过程如图2所示:

(1)使用gcc、gcov对C程序进行编译时加入插桩信息,生成可执行文件;

(2)运行测试全部用例,并统计成功与失败的情况;

(3)对运行生成的覆盖信息日志.gcov文件进行扫描,综合成功与失败的统计结果,获取每行语句的成功覆盖成功未覆盖失败覆盖和失败未覆盖组成的四元组,i表示行号;

(4)选择错误定位的可疑度计算公式Tarantula,公式如下。计算可疑度并按照可疑度降序排序,顺序选择其中一行代码输出给程序预处理模块。

2.程序预处理模块

该模块的实现过程如图3所示:

(1)对从错误定位模块得到的给定的一行作为错误行进行尝试,将其中条件表达式取反后得到程序变异版本;

(2)利用gdb脚本动态执行程序并在该行设置断点,获取执行到该行时可访问的变量列表,具体包括局部变量、全局变量、函数参数、静态变量等;

(3)在该行之前插入打印所有可访问变量的输出语句,目的是将这些变量的运行时值以及条件表达式的计算结果布尔值对应记录。

3.训练数据收集模块,如图4所示。

(1)将原版本和变异版本分别执行全部测试用例并产生测试结果和变量运行时的打印日志;

(2)统计两个版本下用例的成功和失败信息;

(3)对某个用例,产生打印日志如<x1,x2,x3,...,xn,y>,其中表示该行有n个可访问的变量,值分别为x1、x2......该行的条件语句计算结果为y。如果该行在某个用例中被执行多次则产生多条这样的向量记录。从所用用例中选择两版本有且只有一个通过的用例,且仅选取其中通过的版本对应的向量记录加入训练数据集;

(4)根据给定的单个用例中该错误行可执行的次数限制从训练数据集中筛选,组成训练集作为模型学习和补丁生成模块的输入。

4.模型学习和补丁生成模块

该模块的实现过程如图5所示:

(1)用训练集直接进行训练,可设置决策树的最大深度和训练集选取时单个用例中错误执行次数限制,从而获得不同的学习结果;如果在深度限制内未能学到可行的补丁,则从条件语句错误定位模块再获得一行可疑语句向后进行;

(2)对得到的决策树分类器反解析为一段布尔表达式源代码,即生成可直接应用在原程序中的补丁;

5.补丁验证和回归测试模块:

该模块的实现过程如图6所示:

(1)将模型学习和补丁生成模块生成的补丁代码打入原版本程序中替换掉错误条件表达式;

(2)执行全部测试用例,如果全部通过则将其作为一个可行的修复并结束,否则回到模型学习和补丁生成模块,调整决策树深度和错误语句执行次数的阈值,再次学习新补丁。

总之,本发明提出的针对程序源代码中错误条件语句的修复,主要利用条件语句数量较少易于修复,影响程序执行效果明显以及输出为布尔值搜索空间有限等优势,并结合机器学习中监督学习的思想,将程序分析和确定性问题转化为完全依靠数据的概率的学习问题,通过验证与回归测试保证所得结果的可靠性。由于将程序代码结构抽离只分析其数据因此该方法具有很强的鲁棒性;且避免对程序变量进行盲目的尝试组合,充分利用了测试用例提供的信息,可以明显提高自动化修复的速度、成功率和准确度,同时产生可读或语义等价的修复代码。

提供以上实施例仅仅是为了描述本发明的目的,而并非要限制本发明的范围。本发明的范围由所附权利要求限定。不脱离本发明的精神和原理而做出的各种等同替换和修改,均应涵盖在本发明的范围之内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号