一种基于黑盒函数与机器学习的代码测试生成方法和装置与流程

文档序号:15850791发布日期:2018-11-07 09:52阅读:173来源:国知局
一种基于黑盒函数与机器学习的代码测试生成方法和装置与流程

本发明涉及软件分析与测试等领域,尤其涉及测试用例自动生成。

背景技术

步入现代信息社会,计算机软件程序已深入人们的生活,支撑着现代社会发展的方方面面。为保障计算机软件的正确运行,尤其是在经济金融、航天航空等安全相关领域,对程序进行分析验证测试是十分重要的。

然而由于现实程序中往往包含复杂程序结构、复杂非线性约束等复杂程序片段,现有的代码验证测试工具对真实程序的测试覆盖度有限,不能满足对真实代码的测试验证需求。以在软件测试领域被广泛使用的符号执行为例,该技术的主要特征是使用符号化变量代替具体值作为程序输入,在程序分析过程中维护收集分支语句产生的路径约束,并通过求解器求解对应约束生成可触发程序路径的测试用例。在面对复杂真实程序时,符号执行仍面对着因循环等复杂程序结构带来的路径爆炸问题和传统求解器对非线性约束等复杂约束缺乏支持的求解困难问题,对真实代码的测试能力有限。尤其是在处理包含循环等复杂程序结构时,符号执行引擎会将大量系统资源浪费在对循环语句的分析中,阻碍了对后续程序语句的分析测试。为此,当前急需准确而又高效的方法来提高对程序的测试覆盖效率。



技术实现要素:

本发明所要解决的问题:采用符号执行技术对具有复杂程序结构的程序进行分析时带来路径爆炸问题,并由此带来传统约束求解器无法求解复杂约束等问题。

为解决上述问题,本发明采用的方案如下:

根据本发明的一种基于黑盒函数与机器学习的代码测试生成方法,该方法包含以下步骤:

s1:获取被测程序代码和未覆盖节点;所述未覆盖节点为先前程序代码测试时未覆盖到的程序节点;

s2:通过对被测程序代码的静态分析,提取未覆盖路径;所述未覆盖路径为包含未覆盖节点的路径;

s3:静态分析所述未覆盖路径,找出其中的复杂程序代码片段;

s4:抽取所述复杂程序代码片段组成黑盒函数,并将所述未覆盖路径中的所述复杂程序代码片段替换成对所述黑盒函数的调用后,形成包含所述黑盒函数和未覆盖节点的新程序;

s5:对包含所述黑盒函数和未覆盖节点的新程序使用符号执行分析器进行分析,并通过基于学习验证的约束求解器进行求解得到能够覆盖所述未覆盖节点的测试用例数据。

进一步,根据本发明的基于黑盒函数与机器学习的代码测试生成方法,所述步骤s4中“抽取所述复杂程序代码片段组成黑盒函数”包括以下步骤:

s41:根据所述复杂程序代码片段的所处的位置生成所述黑盒函数的函数名;

s42:分析所述复杂程序代码片段中各表达式;将不在该复杂程序代码片段中定义的并且出现在所述表达式右端的变量组成所述黑盒函数的输入变量集;将出现在所述表达式左端的变量组成所述黑盒函数的输出变量集;

s43:将所述黑盒函数的输入变量集打包成所述黑盒函数的输入的结构或类,并构建相应的输入对象实例作为所述黑盒函数的输入变量或输入参数;将所述黑盒函数的输出变量集打包成所述黑盒函数的输出的结构或类,并构建相应的输出对象实例作为所述黑盒函数的输出变量或所述黑盒函数的返回值;

s44:拷贝所述复杂程序代码片段作为所述黑盒函数的函数程序内容,并将其中的变量替换成对应的所述输入对象实例的成员和对应的所述输出对象实例的成员。

根据本发明的一种基于黑盒函数与机器学习的代码测试生成装置,该装置包含以下模块:

m1,用于:获取被测程序代码和未覆盖节点;所述未覆盖节点为先前程序代码测试时未覆盖到的程序节点;

m2,用于:通过对被测程序代码的静态分析,提取未覆盖路径;所述未覆盖路径为包含未覆盖节点的路径;

m3,用于:静态分析所述未覆盖路径,找出其中的复杂程序代码片段;

m4,用于:抽取所述复杂程序代码片段组成黑盒函数,并将所述未覆盖路径中的所述复杂程序代码片段替换成对所述黑盒函数的调用后,形成包含所述黑盒函数和未覆盖节点的新程序;

m5,用于:对包含所述黑盒函数和未覆盖节点的新程序使用符号执行分析器进行分析,并通过基于学习验证的约束求解器进行求解得到能够覆盖所述未覆盖节点的测试用例数据。

进一步,根据本发明的基于黑盒函数与机器学习的代码测试生成装置,所述模块m4中“抽取所述复杂程序代码片段组成黑盒函数”包括以下模块:

m41,用于:根据所述复杂程序代码片段的所处的位置生成所述黑盒函数的函数名;

m42,用于:分析所述复杂程序代码片段中各表达式;将不在该复杂程序代码片段中定义的并且出现在所述表达式右端的变量组成所述黑盒函数的输入变量集;将出现在所述表达式左端的变量组成所述黑盒函数的输出变量集;

m43,用于:将所述黑盒函数的输入变量集打包成所述黑盒函数的输入的结构或类,并构建相应的输入对象实例作为所述黑盒函数的输入变量或输入参数;将所述黑盒函数的输出变量集打包成所述黑盒函数的输出的结构或类,并构建相应的输出对象实例作为所述黑盒函数的输出变量或所述黑盒函数的返回值;

m44,用于:拷贝所述复杂程序代码片段组成所述黑盒函数的程序内容,并将其中的变量替换成对应的所述输入对象实例的成员和对应的所述输出对象实例的成员。

本发明的技术效果如下:本发明将被测程序中的复杂代码替换成黑盒函数,减少了符号执行过程中对复杂代码片段的分析,将更多系统资源分配在对目标结点覆盖的求解上,从而提高了程序分析效率和目标节点的覆盖率。

附图说明

图1是本发明实施例的流程图。

图2是本发明实施例中的被测程序代码示例。

图3是本发明实施例根据图2中的被测程序代码所生成出的程序控制流程图。

图4是本发明实施例根据图3中的程序控制流程图和未覆盖节点所提取的未覆盖路径。

图5是本发明实施例根据图4中的未覆盖路径所找到的复杂程序代码片段。

图6是本发明实施例根据图5中的复杂程序代码片段得到的黑盒函数。

图7是图6中的黑盒函数的程序控制流程图。

图8是对图2中的被测程序代码中的复杂程序代码片段进行黑盒函数替换后得到的程序控制流程图。

图9是本发明实施例所涉及的符号执行技术的模块结构示意图。

具体实施方式

下面结合附图对本发明做进一步详细说明。

如图1所示,本实施例是一种基于黑盒函数与机器学习的代码测试生成方法,按顺序依次包括以下步骤:步骤s1,输入被测程序代码和未覆盖节点;步骤s2,通过对被测程序代码的静态分析,提取未覆盖路径;步骤s3,静态分析未覆盖路径,找出其中的复杂程序代码片段;步骤s4,抽取复杂程序代码片段组成黑盒函数,并将未覆盖路径中的复杂程序代码片段替换成对黑盒函数的调用后,形成包含黑盒函数和未覆盖节点的新程序;步骤s5,对包含黑盒函数和未覆盖节点的新程序使用符号执行分析器进行分析,并通过基于学习验证的约束求解器进行求解得到能够覆盖未覆盖节点的测试用例数据。

本实施例的基于黑盒函数与机器学习的代码测试生成方法的输入是被测程序代码和未覆盖节点。步骤s1中的“输入被测程序代码和未覆盖节点”是相对于用户或者操作者而言,而对于计算机所执行的则是“获取被测程序代码和未覆盖节点”。

未覆盖节点是先前对被测程序代码的测试过程中未能覆盖到的代码段,通常来自原先测试完成后的测试覆盖度报告。未覆盖节点以未能覆盖到的代码段所处的源代码文件、行号以及语句等信息进行表示。以图2中的被测程序代码为例。图2中的被测程序代码为java语言的源代码。其中,第7行中的语句system.out.println("missionequal31finished")为先前测试未能覆盖到的代码段。则未覆盖节点的数据结构可表示成:{sourcefile=...,startline=7,endline=7,specialcode=system.out.println("missionequal31finished")},其中,sourcefile表示未覆盖节点所代表的代码段所在的文件,startline和endline分别表示未覆盖节点所代表的代码段所处的开始行号和结束行号,specialcode表示特征代码。本领域技术人员理解,未覆盖节点的数据结构也可以通过其他方式表示,比如表示成:{funcposition=cal,specialcode=system.out.println("missionequal31finished")},此时,其中的funcposition表示未覆盖节点所代表的代码段所处的函数。

步骤s2“通过对被测程序代码的静态分析,提取未覆盖路径”中的未覆盖路径为包含未覆盖节点的路径。本实施例中,步骤s2包括以下两个步骤:步骤s21,通过对被测程序代码的静态分析获得被测程序代码的程序控制流程图;然后步骤s22,通过深度优先搜索对程序控制流程图进行遍历,找到其中包含有未覆盖节点的未覆盖路径。本实施例中,步骤s21中的程序控制流程图可以通过通用编译器获得,比如本领域技术人员所熟悉的llvm编译器或soot编译器。以图2中的被测程序代码为例,经过soot编译器转化成中间指令后,可得到程序控制流程图如图3所示。再经过步骤s22找到的未覆盖路径如图4所示。

步骤s3“静态分析未覆盖路径,找出其中的复杂程序代码片段”中的复杂程序代码片段,本实施例中是指包含有循环的程序代码段。本实施例中,步骤s3通过两次深度优先搜索查找路径中的循环得到复杂程序代码片段,具体如下:首先使用第一次深度优先搜索遍历程序控制流程图,当发现有回边指向已遍历过的图节点时即为查找到一个可能的循环,进行标记,然后使用第二次深度优先搜索对查找到的循环片段进行排序,确定内外循环顺序等,图5为示例中查找到的循环片段,gotolabel1节点有一条指向label1的回边,而label1已被搜索遍历过。

步骤s4,本实施例具体采用如下步骤:

s41:根据复杂程序代码片段的所处的位置生成黑盒函数的函数名;

s42:分析复杂程序代码片段中各表达式;将不在该复杂程序代码片段中定义的并且出现在表达式右端的变量组成黑盒函数的输入变量集;将出现在表达式左端的变量组成黑盒函数的输出变量集;

s43:将黑盒函数的输入变量集打包成黑盒函数的输入的结构或类,并构建相应的输入对象实例作为黑盒函数的输入变量或输入参数;将黑盒函数的输出变量集打包成黑盒函数的输出的结构或类,并构建相应的输出对象实例作为黑盒函数的输出变量或黑盒函数的返回值;

本领域技术人员理解,步骤s41中黑盒函数的函数名是可以任意的,只要符合语法规范,并且该函数名不与其他函数的函数名冲突即可。用复杂程序代码片段的所处的位置生成黑盒函数的函数名主要是为了查看方便,比如图6中所生成的黑盒函数的函数名cal1x是根据复杂程序代码片段所处的函数名cal加上函数参数名x所形成。

步骤s42以图5中的复杂程序代码片段为例,变量i2曾出现在表达式($i1=i2*5)的右端,记为黑盒函数的输入变量,变量i2曾出现在表达式(i2=$i1+1)的左端,记为黑盒函数的输出变量,最终生成的黑盒函数如图6所示。图7为图6所示的黑盒函数所对应的程序控制流程图。由于图5所示的示例代码较为简单,因此该生成的黑盒函数的输入变量和输出变量均只有1个。考虑更为复杂的代码情形,黑盒函数的输入变量和输出变量均存在多个的情形,此时,这些输入变量则组成输入变量集,输出变量则组成输出变量集。

考虑到黑盒函数可能存在的输入变量和输出变量很多的情形,因此本实施例步骤s43中,将输入变量集和输出变量集打包成一个结构或类的方式作为黑盒函数的输入或输出。本领域技术人员理解,在输入变量和输出变量较多的情形下,黑盒函数的打包方式还有很多种,比如,直接将输入变量和输出变量以及黑盒函数打包组成测试类,输入变量和输出变量为该测试类的成员,而黑盒函数则是该测试类的方法。如图8所示,图8是图3中的程序控制流程图经步骤s4处理后得到将复杂程序代码片段(也即循环片段)替换成黑盒函数后的程序控制流程图,其中,$i2copy=test.cal1x(i2)为原先复杂程序代码片段替换成黑盒函数而成,其中test为黑盒函数打包封装成的测试类,cal1x为该测试类的方法。由图8可以看出削减掉了循环语句的分支和节点后,程序控制流程图变得更为清晰明了。

步骤s5中的过程为本领域技术人员所熟悉的符号执行技术。不同于传统的符号执行技术,本实施例采用了基于学习验证的约束求解器,并由此带来了一些细节上的不同:首先,本实施例符号执行分析器对包含黑盒函数和未覆盖节点的新程序使用进行分析时,并不对黑盒函数进行分析,而是直接调用黑盒函数,由此符号执行分析器所输出的路径约束并非完全是由符号化变量表示,而是包含黑盒函数调用的路径约束,如对图8中的程序,生成路径约束{test.cal1x(i2)==131},其中i2为符号化变量,test.cal1x为黑盒函数调用。符号执行分析器调用黑盒函数时,黑盒函数输入变量的数值与对应的符号化变量赋值相同,符号化变量的赋值初始时随机采样产生。符号执行分析器对当前采样样本赋值进行验证,假如验证符合路径约束有解,则输出这些解作为测试用例数据;假如无解,则通过机器学习的方法对当前样本的验证结果进行分析生成新的一组输入变量值样本,然后再调用符号执行分析器重复进行分析验证,直到有解或者轮次数超过限值。如对路径约束{test.cal1x(i2)==131},某轮采样样本为(i2=0),黑盒函数调用执行test.cal1x(0)的返回值为156,验证路径约束表达式左值和右值的相等性,1不符合,则反馈相关信息给机器学习模块继续采样;某轮采样样本为(i2=131),黑盒函数调用执行test.cal1x(131)的返回值为131,验证131==131符合,则使用该样本生成可触发目标节点的一组测试用例;本领域技术人员理解,采样样本验证的相关信息,除基本的验证符合或不符合外,还可以附加验证路径约束表达式的左右绝对值差等其他信息,以帮助机器学习模块尽快有效采样求解出符合路径约束的样本。上述符号执行技术的过程通过模块进行表述,如图9所示,步骤s5由机器学习模块901、控制模块902、符号执行分析器903所共同实现。其中,机器学习模块901用于通过机器学习的方法生成符号化变量的数值作为一组样本,这些符号化变量对应于黑盒函数调用的输入变量数值;符号执行分析器903用于对包含黑盒函数和未覆盖节点的新程序进行符号执行分析输出路径约束和验证输入变量是否符合路径约束;控制模块902则用于机器学习模块901和符号执行分析器903之间的控制调度。本实施例中,符号执行分析器903采用mlbse,mlbse是一种基于学习验证的约束求解器和符号执行分析器,具体可参照https://github.com/mlb-se,本说明书不再赘述。

步骤s5所输出的测试用例数据即为本实施例的基于黑盒函数与机器学习的代码测试生成方法的最终输出,由此测试工程师可以根据这些测试用例数据进行测试,从而使得被测程序代码中的未覆盖节点能够被测试覆盖。本领域技术人员理解,步骤s5存在最终无法输出测试用例数据的情形。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1