一种测试脚本断言生成方法及装置
文献发布时间:2023-06-19 11:08:20
技术领域
本申请涉及计算机技术领域,具体涉及测试脚本断言生成方法及装置。
背景技术
在软件测试过程中,自动化测试是一种常见的测试手段。自动化测试脚本的断言一般是通过工具生成,或是测试人员手工编写。对于通过工具生成的自动化测试脚本断言,一般是只对交易结果进行简单的断言,或是通过预配置生成了特定组合的断言,没有针对测试场景做精准断言;对于测试人员手工编写的断言,若测试人员对被测功能不够熟悉,那么就可能出现遗漏关键字段断言,或是写错断言预期结果的情况。
发明内容
针对现有技术中的问题,本申请提供一种测试脚本断言生成方法及装置,方法包括:解析目标源代码,生成所述目标源代码的数据血缘关系;根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。本申请规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
本发明的一方面,提供一种测试脚本断言生成方法,包括:
解析目标源代码,生成所述目标源代码的数据血缘关系;
根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。
在优选的实施例中,所述解析目标源代码,生成所述目标源代码的数据血缘关系,包括:
对所述目标源代码进行词法分析;
根据所述词法分析得出的语句类型,建立目标源代码的数据血缘关系。
在优选的实施例中,还包括:将所述目标源代码划分为多个代码单元;所述对所述目标源代码进行词法分析,包括:分别对每个代码单元进行词法分析。
在优选的实施例中,所述代码单元为一行代码,或者所述代码单元包括设定字符长度。
在优选的实施例中,所述根据所述词法分析得出的语句类型,建立目标源代码的数据血缘关系,包括:
按照每个代码单元所处目标源代码中的先后顺序,逐一判断每个代码单元的语句类型;
基于所述语句类型按照设定规则执行至少一个构建操作,得到所述目标源代码的数据血缘关系。
在优选的实施例中,所述数据血缘关系包括多个数据血缘单元,每个数据血缘单元包括:判断正确列表、判断错误列表以及判断条件语句;基于所述语句类型按照设定规则执行至少一个构建操作,包括:
若所述代码单元的语句类型为赋值语句,将所述代码单元插入至相对的上一层级数据血缘单元中的判断正确列表;
若所述代码单元的语句类型为判断语句,创建相对的下一层级数据血缘单元,并将所述代码单元记录至该下一层级数据血缘单元的判断条件语句,将该下一层级数据血缘单元插入至相对的上一层级数据单元中,将所述代码单元中判断为正确的分支插入该下一层级数据血缘单元的判断正确列表,判断为错误的分支插入该下一层级数据血缘单元的判断错误列表。
在优选的实施例中,所述根据所述数据血缘关系生成一断言类,包括:
遍历数据血缘关系中所有的数据血缘单元;
根据所述数据血缘单元中记录的语句类型,生成相应的断言语句,进而生成所述断言类。
在优选的实施例中,所述根据所述数据血缘单元中记录的语句类型,生成相应的断言语句,包括:
若所述语句类型为赋值语句,则将该赋值语句作为其对应的断言语句;
若所述语句类型为判断语句,则将记录的判断条件语句作为断言语句的判断条件,将记录的判断正确列表作为断言语句正确的分支,将记录的判断错误列表作为断言语句错误的分支;
若所述语句类型为数据库操作语句,根据数据库操作类型生成相应的断言语句。
在优选的实施例中,所述根据数据库操作类型生成相应的断言语句,包括:
若所述数据库操作类型为插入,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将1作为断言的期望值,生成相应的断言语句;
若所述数据库操作类型为更新,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将源代码对应的数据库语句中的键值代表的变量作为断言的期望值,根据查询条件字段依次生成相应的断言语句;
若所述数据库操作类型为删除,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将0作为断言的期望值,生成相应的断言语句。
本发明的又一方面,提供一种测试脚本断言生成装置,包括:
数据血缘关系生成模块,解析目标源代码,生成所述目标源代码的数据血缘关系;
断言类生成模块,根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。
在优选的实施例中,所述数据血缘关系生成模块,包括:
词法分析单元,对所述目标源代码进行词法分析;
数据血缘关系建立单元,根据所述词法分析得出的语句类型,建立目标源代码的数据血缘关系。
在优选的实施例中,还包括:代码单元划分单元,具体用于将所述目标源代码划分为多个代码单元;所述词法分析单元,具体用于分别对每个代码单元进行词法分析。
在优选的实施例中,所述代码单元为一行代码,或者所述代码单元包括设定字符长度。
在优选的实施例中,所述数据血缘关系建立单元,包括:
代码单元类型判断单元,按照每个代码单元所处目标源代码中的先后顺序,逐一判断每个代码单元的语句类型;
数据血缘关系构建单元,基于所述语句类型按照设定规则执行至少一个构建操作,得到所述目标源代码的数据血缘关系。
在优选的实施例中,所述数据血缘关系包括多个数据血缘单元,每个数据血缘单元包括:判断正确列表、判断错误列表以及判断条件语句;所述数据血缘关系构建单元,包括:
赋值语句构建单元,若所述代码单元的语句类型为赋值语句,将所述代码单元插入至相对的上一层级数据血缘单元中的判断正确列表;
判断语句构建单元,若所述代码单元的语句类型为判断语句,创建相对的下一层级数据血缘单元,并将所述代码单元记录至该下一层级数据血缘单元的判断条件语句,将该下一层级数据血缘单元插入至相对的上一层级数据单元中,将所述代码单元中判断为正确的分支插入该下一层级数据血缘单元的判断正确列表,判断为错误的分支插入该下一层级数据血缘单元的判断错误列表。
在优选的实施例中,所述断言类生成模块,包括:
遍历单元,遍历数据血缘关系中所有的数据血缘单元;
断言生成单元,根据所述数据血缘单元中记录的语句类型,生成相应的断言语句,进而生成所述断言类。
在优选的实施例中,所述断言生成单元,包括:
赋值语句断言生成单元,若所述语句类型为赋值语句,则将该赋值语句作为其对应的断言语句;
判断语句断言生成单元,若所述语句类型为判断语句,则将记录的判断条件语句作为断言语句的判断条件,将记录的判断正确列表作为断言语句正确的分支,将记录的判断错误列表作为断言语句错误的分支;
数据库操作语句断言生成单元,若所述语句类型为数据库操作语句,根据数据库操作类型生成相应的断言语句。
在优选的实施例中,所述数据库操作语句断言生成单元,包括:
插入操作断言生成单元,若所述数据库操作类型为插入,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将1作为断言的期望值,生成相应的断言语句;
更新操作断言生成单元,若所述数据库操作类型为更新,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将源代码对应的数据库语句中的键值代表的变量作为断言的期望值,根据查询条件字段依次生成相应的断言语句;
删除操作断言生成单元,若所述数据库操作类型为删除,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将0作为断言的期望值,生成相应的断言语句。
本发明的又一方面,本申请提供一种电子设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述处理器执行所述程序时实现所述的测试脚本断言生成方法。
本发明的又一方面,本申请提供一种计算机可读存储介质,其上存储有计算机程序,该计算机程序被处理器执行时实现所述的测试脚本断言生成方法。
由上述技术方案可知,本申请提供的一种测试脚本断言生成方法,方法包括:解析目标源代码,生成所述目标源代码的数据血缘关系;根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。本申请规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
附图说明
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1是测试脚本断言生成方法流程示意图。
图2是数据血缘关系生成流程示意图。
图3是断言方法生成流程示意图。
图4是一具体实施例中的数据血缘关系示意图。
图5是测试脚本断言生成装置结构示意图。
图6是本申请实施例中的电子设备的结构示意图。
具体实施方式
为使本申请实施例的目的、技术方案和优点更加清楚,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整的描述,显然,所描述的实施例是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
需要说明的是,本申请公开的测试脚本断言生成方法及装置可用于信息安全领域,也可用于除信息安全领域之外的任意领域,本申请公开的测试脚本断言生成方法及装置的应用领域不做限定。
在软件测试过程中,自动化测试是一种常见的测试手段。自动化测试脚本的断言一般是通过工具生成,或是测试人员手工编写。对于通过工具生成的自动化测试脚本断言,一般是只对交易结果进行简单的断言,或是通过预配置生成了特定组合的断言,没有针对测试场景做精准断言;对于测试人员手工编写的断言,若测试人员对被测功能不够熟悉,那么就可能出现遗漏关键字段断言,或是写错断言预期结果的情况。
为了解决现有问题中的至少一个,本申请提供一种测试脚本断言生成方法及装置,方法包括:解析目标源代码,生成所述目标源代码的数据血缘关系;根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。本申请规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
下面结合附图对本发明提供的测试脚本断言生成方法及装置进行详细说明。
在具体的实施例中,本申请提供一种测试脚本断言生成方法,如图1,包括:
S1:解析目标源代码,生成所述目标源代码的数据血缘关系;
具体的,数据的产生、加工融合、流转流通,到最终消亡,数据之间自然会形成一种关系。借鉴人类社会中类似的一种关系来表达数据之间的这种关系,称之为数据的血缘关系。通过对源代码的数据血缘关系,可以追溯到任意变量的来源和加工过程,从而便于精准地生成测试脚本的断言。所述解析目标源代码,生成所述目标源代码的数据血缘关系,如图2,包括:
S11:对所述目标源代码进行词法分析;
具体的,对于数据血缘关系的建立,依赖于代码的词法分析。在具体的实施例中,将所述目标源代码划分为多个代码单元;分别对每个代码单元进行词法分析。其中,所述代码单元为一行代码,或者所述代码单元包括设定字符长度。在具体的实施例中,所述代码单元包括设定字符长度,可以理解为该代码单元包括了多行代码,且该多行代码归属于同一个语法结构,例如循环语法,判断语法,该些语法结构都包含了多行源代码。举例而言,假设目标源代码包括了如下语句:int a=1;int b=2;if(a>b){a=0}else{b=0};将该源代码划分为三个代码单元,分别为单元一:int a=1单元二:int b=2单元三:if(a>b){a=0}else{b=0}。将源代码划分为多个代码单元后,分别对每个代码单元进行词法分析,得到对应代码单元的语句类型。通过词法分析可知,上述三个代码单元对应的语句类型如下:代码单元一为赋值语句,代码单元二为赋值语句,代码单元三为判断语句。
S12:根据所述词法分析得出的语句类型,建立目标源代码的数据血缘关系。
具体的,通过对源代码的词法分析,可以得到代码的语句类型,根据语句类型建立目标代码的数据血缘关系。可以理解,对于数据血缘关系的生成可以有两种方式,一种方式为解析出一个代码单元的语句类型后在数据血缘关系中添加其相应的信息,另一种方式为将所有代码单元的语句类型全部获取,然后再建立数据血缘关系。两种方式都是可行且有效的。所述根据所述词法分析得出的语句类型,建立目标源代码的数据血缘关系,包括:
按照每个代码单元所处目标源代码中的先后顺序,逐一判断每个代码单元的语句类型,并基于所述语句类型按照设定规则执行至少一个构建操作,得到所述目标源代码的数据血缘关系。所述数据血缘关系包括多个数据血缘单元,每个数据血缘单元包括:判断正确列表、判断错误列表以及判断条件语句,基于所述语句类型按照设定规则执行至少一个构建操作,包括:
若所述代码单元的语句类型为赋值语句,将所述代码单元插入至相对的上一层级数据血缘单元中的判断正确列表;
若所述代码单元的语句类型为判断语句,创建相对的下一层级数据血缘单元,并将所述代码单元记录至该下一层级数据血缘单元的判断条件语句,将该下一层级数据血缘单元插入至相对的上一层级数据单元中,将所述代码单元中判断为正确的分支插入该下一层级数据血缘单元的判断正确列表,判断为错误的分支插入该下一层级数据血缘单元的判断错误列表。
在具体的实施例中,假设目标源代码有四个代码单元,其中其所处的先后顺序,命名为代码单元一、二、三、四。通过词法分析得到代码单元一为判断语句,代码单元二为赋值语句,代码单元三也是判断语句,代码单元四为也为判断语句,其中代码单元一,二,三为同一层次,代码单元四为代码单元三中的下一层次。在建立数据血缘关系时,首先生成一个初始的数据血缘单元analysesClass0,由于代码单元一为判断语句,则新建立一数据血缘单元analysesClass1,将analysesClass1插入analysesClass0的判断正确列表中,然后对analysesClass1的具体内容进行填充,将代码单元一的判断条件插入analysesClass1的判断条件语句,代码单元一的判断正确的分支插入analysesClass1的判断正确列表,将代码单元一的判断错误的分支插入analysesClass1的判断错误列表。至此完成对代码单元一的操作,开始对代码单元二进行分析,代码单元二为赋值语句,直接将代码单元二的赋值语句插入analysesClass0的正确列表,完成代码单元二的操作。对于代码单元三,由于其为判断语句,故新建立一个数据血缘单元analysesClass2,将analysesClass2插入analysesClass0的判断正确列表,然后根据代码单元三的内容对analysesClass2进行填充,将代码单元三的判断条件插入analysesClass2的判断条件语句,将对应的正确分支插入analysesClass2的判断正确列表,将对应的错误分支插入analysesClass2的判断错误列表。在填充过程中,对应的正确分支包括了代码单元四,代码单元四也是一个判断语句类型,所以新建一个数据血缘单元analysesClass3,将analysesClass3插入至analysesClass2的判断正确列表中,然后根据代码单元四的内容对analysesClass3进行填充。最后完成了对整个目标源代码的数据血缘关系解析,生成了数据血缘关系。
S2:根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。
具体的,生成了目标源代码的数据血缘关系后,源代码中所有数据的来源及加工过程就清晰明了了。通过数据血缘关系可以精准地进行断言,生成一个用于断言的断言类,该断言类包括了一个断言方法,所述断言方法中包括了对目标源代码所有数据操作的断言。在生成测试脚本时,可以直接调用该断言类的断言方法,对目标源代码的数据操作进行断言。在具体的实施例中,所述根据所述数据血缘关系生成一断言类,如图3,包括:
S21:遍历数据血缘关系中所有的数据血缘单元;
具体的,数据血缘关系中包含了多个数据血缘单元,这些数据血缘单元中记录了源代码的数据语句信息,所以遍历数据血缘关系中所有的数据血缘单元,即可以理解为遍历了整个目标源代码,进而保证了后续断言方法可以覆盖所有目标源代码的数据。
S22:根据所述数据血缘单元中记录的语句类型,生成相应的断言语句,进而生成所述断言类。
具体的,对于不同的语句类型,其对应的断言语句是不同的。在具体的实施例中,若所述语句类型为赋值语句,则将该赋值语句作为其对应的断言语句。例如源代码的赋值语句为int example=6,则写入断言方法中的断言语句为int example=6,即断言语句与源代码语句是一致的。若所述语句类型为判断语句,则将记录的判断条件语句作为断言语句的判断条件,将记录的判断正确列表作为断言语句正确的分支,将记录的判断错误列表作为断言语句错误的分支。例如源代码中判断语句为if(a>b){a=0;printf(a)}else{b=100;printf(b)},该判断语句的判断条件语句为a>b,其判断正确列表中记录的语句应为a=0,判断错误列表里记录的语句应为b.=100,所以该判断语句对应生成的断言语句应为if(a>b){a=0}else{b=100;printf(b)}。
在具体的实施例中,若所述语句类型为数据库操作语句,根据数据库操作类型生成相应的断言语句。其中,语句类型为数据库操作语句需要根据具体的数据库操作类型来进一步细分:若所述数据库操作类型为插入,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将1作为断言的期望值,生成相应的断言语句。例如源代码中的数据库操作语句为DBExecutor.insert(AtDBMapper.insert_MedLimtTable,input),其对应的数据库语句为:
该插入的键名为insert_MedLimtTable,所以在断言映射文件中相应生成的查询记录为
若插入成功,则该查询记录的返回表记录数为1,若不成功则返回表记录数为0,因此将返回表记录数作为断言的实际值,将1作为断言期望值,生成如下的断言语句:
Assert.assertEquals(DBExecutor.insert(“AtDBMapper.insert_MedLimitTable”,input),1)
若所述数据库操作类型为更新,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将源代码对应的数据库语句中的键值代表的变量作为断言的期望值,根据查询条件字段依次生成相应的断言语句。例如源代码中数据库操作语句为DBExecutor.update(AtDBMapper.update_medium_with_cardno,input),该语句对应的数据库语句为
其键名为update_MedLimitTable_by_cardno,故相应在断言映射文件中相应生成的查询记录为
若更新成功,则查询出的各字段数值应与输入数值一致,故键值代表的变量作为断言的期望值,根据查询条件字段依次生成相应的断言语句,如下所示:
tmpBean=DBExecutor.update(“AtDBMapper.insert_MedLimitTable”,input);
Assert.assertEquals(tmpBean.limit_amout,input.limit_amout);
Assert.assertEquals(tmpBean.status,input.status);
若所述数据库操作类型为删除,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将0作为断言的期望值,生成相应的断言语句。例如源代码中的数据库操作语句为DBExecutor.delete(AtDBMapper.delete_MedLimtTable,input),其对应的数据库语句为:
该插入的键名为delete_MedLimtTable,所以在断言映射文件中相应生成的查询记录为
若删除成功,则该查询记录的返回表记录数为0,若不成功则返回表记录数为1,因此将返回表记录数作为断言的实际值,将0作为断言期望值,生成如下的断言语句:
Assert.assertEquals(DBExecutor.delete(“AtDBMapper.insert_MedLimitTable”,input),0)
结合一具体场景对本发明作进一步说明,现有一目标源代码,根据其生成相应的测试脚本断言用于对目标源代码的测试。根据本申请提供的方法,首先对目标源代码进行词法分析,将目标源代码划分为多个代码单元,每个代码单元可以是一行代码,也可以是多行代码,在本实施例中,将目标源代码划分为五个,其中代码单元一,二为同一层次,代码单元三,四,五为代码单元二的下一层次。分别对每个代码单元进行词法分析,得到每个代码单元的语句类型,代码单元一为赋值语句,代码单元二为判断语句,代码单元三为数据库操作语句,代码单元四为判断语句,代码单元五为数据库操作语句。根据本申请提供的生成数据血缘关系的步骤,首先建立一个初始化的数据血缘单元analysesClass0,由于代码单元一是一个赋值语句,将analysesClass0的判断条件和判断错误列表置为空值,将代码单元一的赋值语句插入analysesClass0的判断正确列表。然后判断下一个代码单元的语句类型,代码单元二为判断语句,则需要建立一个新的数据血缘单元analysesClass1,将其整体插入analysesClass0的判断正确列表中,然后对analysesClass1的内容进行填充,将代码单元二中的判断条件置于analysesClass1的判断条件中,将代码单元二中判断正确的分支插入analysesClass1的判断正确列表,将代码单元二中判断错误的分支插入analysesClass1的判断错误列表。代码单元三处于代码单元二的正确分支中,其为数据库操作语句,则直接将数据库操作语句插入analysesClass1的判断正确列表。代码单元四处于代码单元二的错误分支中,其为一个赋值语句,直接插入analysesClass1的错误分支中。代码单元五处于代码单元二的错误分支中,其为数据库操作语句类型,则直接将代码单元五的数据库操作语句插入analysesClass1的判断错误列表。至此可以生成源代码的数据血缘关系,如图4所示。
生成数据血缘关系后,遍历数据血缘关系中所有的数据血缘单元,根据数据血缘单元记录的语句类型,生成包含有断言方法的断言类。在本实施场景中,从analysesClass0开始,其记录的第一条为一个赋值语句,故直接将该赋值语句写入断言方法中。记录的第二条为analysesClass1,对应一个判断语句,故将analysesClass1中记录的判断条件写入断言语句的判断条件中,将analysesClass1的判断正确列表中记录的内容写入断言语句的正确分支,判断错误列表写入断言语句的错误分支。以此类推,最终生成如下的断言类:
Public class AssertDemoClass{
Public viod assertFunction(DemoClassBean input){
Input.limit_amout=input.limit_amout+100;
If(input.operflag==1){
Assert.assertEquals(DBExecutor.insert(“AtDBMapper.insert_MedLimitTable”,input),1);
Else
{
Input.status=1;
DemoClassBean
tmpBean=DBExcutor.update(“AtDBMapper.insert_MedLimitTable”,input);
Assert.assertEquals(tmpBean.limit_amout,input.limit_amout);
Assert.assertEquals(tmpBean.status,input.status);
}
}
}
}
由以上描述可知,本发明提供的一种测试脚本断言生成方法,方法包括:解析目标源代码,生成所述目标源代码的数据血缘关系;根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。本申请规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
从软件层面来说,本申请提供一种用于执行所述测试脚本断言生成方法中全部或部分内容的测试脚本断言生成装置的实施例,参见图5,所述测试脚本断言生成装置具体包含有如下内容:
数据血缘关系生成模块1,解析目标源代码,生成所述目标源代码的数据血缘关系;
断言类生成模块2,根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。
由以上描述可知,本发明提供的测试脚本断言生成装置,本装置首先解析目标源代码,生成所述目标源代码的数据血缘关系;然后根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。本申请规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
在具体的实施例中,本申请提供一种测试脚本断言生成装置,包括:
数据血缘关系生成模块1,用于执行解析目标源代码,生成所述目标源代码的数据血缘关系;
具体的,数据的产生、加工融合、流转流通,到最终消亡,数据之间自然会形成一种关系。借鉴人类社会中类似的一种关系来表达数据之间的这种关系,称之为数据的血缘关系。通过对源代码的数据血缘关系,可以追溯到任意变量的来源和加工过程,从而便于精准地生成测试脚本的断言。在具体的实施例中,所述数据血缘关系生成模块,具体执行如下步骤包括:
S11:对所述目标源代码进行词法分析;
具体的,对于数据血缘关系的建立,依赖于代码的词法分析。在具体的实施例中,将所述目标源代码划分为多个代码单元;分别对每个代码单元进行词法分析。其中,所述代码单元为一行代码,或者所述代码单元包括设定字符长度。在具体的实施例中,所述代码单元包括设定字符长度,可以理解为该代码单元包括了多行代码,且该多行代码归属于同一个语法结构,例如循环语法,判断语法,该些语法结构都包含了多行源代码。举例而言,假设目标源代码包括了如下语句:int a=1;int b=2;if(a>b){a=0}else{b=0};将该源代码划分为三个代码单元,分别为单元一:int a=1单元二:int b=2单元三:if(a>b){a=0}else{b=0}。将源代码划分为多个代码单元后,分别对每个代码单元进行词法分析,得到对应代码单元的语句类型。通过词法分析可知,上述三个代码单元对应的语句类型如下:代码单元一为赋值语句,代码单元二为赋值语句,代码单元三为判断语句。
S12:根据所述词法分析得出的语句类型,建立目标源代码的数据血缘关系。
具体的,通过对源代码的词法分析,可以得到代码的语句类型,根据语句类型建立目标代码的数据血缘关系。可以理解,对于数据血缘关系的生成可以有两种方式,一种方式为解析出一个代码单元的语句类型后在数据血缘关系中添加其相应的信息,另一种方式为将所有代码单元的语句类型全部获取,然后再建立数据血缘关系。两种方式都是可行且有效的。所述根据所述词法分析得出的语句类型,建立目标源代码的数据血缘关系,包括:
按照每个代码单元所处目标源代码中的先后顺序,逐一判断每个代码单元的语句类型,并基于所述语句类型按照设定规则执行至少一个构建操作,得到所述目标源代码的数据血缘关系。所述数据血缘关系包括多个数据血缘单元,每个数据血缘单元包括:判断正确列表、判断错误列表以及判断条件语句,基于所述语句类型按照设定规则执行至少一个构建操作,包括:
若所述代码单元的语句类型为赋值语句,将所述代码单元插入至相对的上一层级数据血缘单元中的判断正确列表;
若所述代码单元的语句类型为判断语句,创建相对的下一层级数据血缘单元,并将所述代码单元记录至该下一层级数据血缘单元的判断条件语句,将该下一层级数据血缘单元插入至相对的上一层级数据单元中,将所述代码单元中判断为正确的分支插入该下一层级数据血缘单元的判断正确列表,判断为错误的分支插入该下一层级数据血缘单元的判断错误列表。
在具体的实施例中,假设目标源代码有四个代码单元,其中其所处的先后顺序,命名为代码单元一、二、三、四。通过词法分析得到代码单元一为判断语句,代码单元二为赋值语句,代码单元三也是判断语句,代码单元四为也为判断语句,其中代码单元一,二,三为同一层次,代码单元四为代码单元三中的下一层次。在建立数据血缘关系时,首先生成一个初始的数据血缘单元analysesClass0,由于代码单元一为判断语句,则新建立一数据血缘单元analysesClass1,将analysesClass1插入analysesClass0的判断正确列表中,然后对analysesClass1的具体内容进行填充,将代码单元一的判断条件插入analysesClass1的判断条件语句,代码单元一的判断正确的分支插入analysesClass1的判断正确列表,将代码单元一的判断错误的分支插入analysesClass1的判断错误列表。至此完成对代码单元一的操作,开始对代码单元二进行分析,代码单元二为赋值语句,直接将代码单元二的赋值语句插入analysesClass0的正确列表,完成代码单元二的操作。对于代码单元三,由于其为判断语句,故新建立一个数据血缘单元analysesClass2,将analysesClass2插入analysesClass0的判断正确列表,然后根据代码单元三的内容对analysesClass2进行填充,将代码单元三的判断条件插入analysesClass2的判断条件语句,将对应的正确分支插入analysesClass2的判断正确列表,将对应的错误分支插入analysesClass2的判断错误列表。在填充过程中,对应的正确分支包括了代码单元四,代码单元四也是一个判断语句类型,所以新建一个数据血缘单元analysesClass3,将analysesClass3插入至analysesClass2的判断正确列表中,然后根据代码单元四的内容对analysesClass3进行填充。最后完成了对整个目标源代码的数据血缘关系解析,生成了数据血缘关系。
可以理解的是,所述数据血缘关系生成模块执行上述步骤可以理解为包括词法分析单元,数据血缘关系建立单元,其中词法分析单元执行S11步骤,数据血缘关系建立单元执行S12步骤,后续相关实施例不在赘述。
断言类生成模块2,用于执行根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。
具体的,生成了目标源代码的数据血缘关系后,源代码中所有数据的来源及加工过程就清晰明了了。通过数据血缘关系可以精准地进行断言,生成一个用于断言的断言类,该断言类包括了一个断言方法,所述断言方法中包括了对目标源代码所有数据操作的断言。在生成测试脚本时,可以直接调用该断言类的断言方法,对目标源代码的数据操作进行断言。在具体的实施例中,所述断言类生成模块,具体执行如下步骤包括:
S21:遍历数据血缘关系中所有的数据血缘单元;
具体的,数据血缘关系中包含了多个数据血缘单元,这些数据血缘单元中记录了源代码的数据语句信息,所以遍历数据血缘关系中所有的数据血缘单元,即可以理解为遍历了整个目标源代码,进而保证了后续断言方法可以覆盖所有目标源代码的数据。
S22:根据所述数据血缘单元中记录的语句类型,生成相应的断言语句,进而生成所述断言类。
具体的,对于不同的语句类型,其对应的断言语句是不同的。在具体的实施例中,若所述语句类型为赋值语句,则将该赋值语句作为其对应的断言语句。例如源代码的赋值语句为int example=6,则写入断言方法中的断言语句为int example=6,即断言语句与源代码语句是一致的。若所述语句类型为判断语句,则将记录的判断条件语句作为断言语句的判断条件,将记录的判断正确列表作为断言语句正确的分支,将记录的判断错误列表作为断言语句错误的分支。例如源代码中判断语句为if(a>b){a=0;printf(a)}else{b=100;printf(b)},该判断语句的判断条件语句为a>b,其判断正确列表中记录的语句应为a=0,判断错误列表里记录的语句应为b.=100,所以该判断语句对应生成的断言语句应为if(a>b){a=0}else{b=100;printf(b)}。
在具体的实施例中,若所述语句类型为数据库操作语句,根据数据库操作类型生成相应的断言语句。其中,语句类型为数据库操作语句需要根据具体的数据库操作类型来进一步细分:若所述数据库操作类型为插入,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将1作为断言的期望值,生成相应的断言语句。例如源代码中的数据库操作语句为DBExecutor.insert(AtDBMapper.insert_MedLimtTable,input),其对应的数据库语句为:
该插入的键名为insert_MedLimtTable,所以在断言映射文件中相应生成的查询记录为
若插入成功,则该查询记录的返回表记录数为1,若不成功则返回表记录数为0,因此将返回表记录数作为断言的实际值,将1作为断言期望值,生成如下的断言语句:
Assert.assertEquals(DBExecutor.insert(“AtDBMapper.insert_MedLimitTable”,input),1)
若所述数据库操作类型为更新,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将源代码对应的数据库语句中的键值代表的变量作为断言的期望值,根据查询条件字段依次生成相应的断言语句。例如源代码中数据库操作语句为DBExecutor.update(AtDBMapper.update_medium_with_cardno,input),该语句对应的数据库语句为
其键名为update_MedLimitTable_by_cardno,故相应在断言映射文件中相应生成的查询记录为
若更新成功,则查询出的各字段数值应与输入数值一致,故键值代表的变量作为断言的期望值,根据查询条件字段依次生成相应的断言语句,如下所示:
tmpBean=DBExecutor.update(“AtDBMapper.insert_MedLimitTable”,input);
Assert.assertEquals(tmpBean.limit_amout,input.limit_amout);
Assert.assertEquals(tmpBean.status,input.status);
若所述数据库操作类型为删除,在预设的断言映射文件中增加一条和源代码数据库映射文件中键同名的查询记录,将返回表记录数作为断言的实际值,将0作为断言的期望值,生成相应的断言语句。例如源代码中的数据库操作语句为DBExecutor.delete(AtDBMapper.delete_MedLimtTable,input),其对应的数据库语句为:
该插入的键名为delete_MedLimtTable,所以在断言映射文件中相应生成的查询记录为
若删除成功,则该查询记录的返回表记录数为0,若不成功则返回表记录数为1,因此将返回表记录数作为断言的实际值,将0作为断言期望值,生成如下的断言语句:
Assert.assertEquals(DBExecutor.delete(“AtDBMapper.insert_MedLimitTable”,input),0)
结合一具体场景对本发明作进一步说明,现有一目标源代码,根据其生成相应的测试脚本断言用于对目标源代码的测试。根据本申请提供的方法,首先对目标源代码进行词法分析,将目标源代码划分为多个代码单元,每个代码单元可以是一行代码,也可以是多行代码,在本实施例中,将目标源代码划分为五个,其中代码单元一,二为同一层次,代码单元三,四,五为代码单元二的下一层次。分别对每个代码单元进行词法分析,得到每个代码单元的语句类型,代码单元一为赋值语句,代码单元二为判断语句,代码单元三为数据库操作语句,代码单元四为判断语句,代码单元五为数据库操作语句。根据本申请提供的生成数据血缘关系的步骤,首先建立一个初始化的数据血缘单元analysesClass0,由于代码单元一是一个赋值语句,将analysesClass0的判断条件和判断错误列表置为空值,将代码单元一的赋值语句插入analysesClass0的判断正确列表。然后判断下一个代码单元的语句类型,代码单元二为判断语句,则需要建立一个新的数据血缘单元analysesClass1,将其整体插入analysesClass0的判断正确列表中,然后对analysesClass1的内容进行填充,将代码单元二中的判断条件置于analysesClass1的判断条件中,将代码单元二中判断正确的分支插入analysesClass1的判断正确列表,将代码单元二中判断错误的分支插入analysesClass1的判断错误列表。代码单元三处于代码单元二的正确分支中,其为数据库操作语句,则直接将数据库操作语句插入analysesClass1的判断正确列表。代码单元四处于代码单元二的错误分支中,其为一个赋值语句,直接插入analysesClass1的错误分支中。代码单元五处于代码单元二的错误分支中,其为数据库操作语句类型,则直接将代码单元五的数据库操作语句插入analysesClass1的判断错误列表。至此可以生成源代码的数据血缘关系,如图4所示。
生成数据血缘关系后,遍历数据血缘关系中所有的数据血缘单元,根据数据血缘单元记录的语句类型,生成包含有断言方法的断言类。在本实施场景中,从analysesClass0开始,其记录的第一条为一个赋值语句,故直接将该赋值语句写入断言方法中。记录的第二条为analysesClass1,对应一个判断语句,故将analysesClass1中记录的判断条件写入断言语句的判断条件中,将analysesClass1的判断正确列表中记录的内容写入断言语句的正确分支,判断错误列表写入断言语句的错误分支。以此类推,最终生成如下的断言类:
Public class AssertDemoClass{
Public viod assertFunction(DemoClassBean input){
Input.limit_amout=input.limit_amout+100;
If(input.operflag==1){
Assert.assertEquals(DBExecutor.insert(“AtDBMapper.insert_MedLimitTable”,input),1);
Else
{
Input.status=1;
DemoClassBean
tmpBean=DBExcutor.update(“AtDBMapper.insert_MedLimitTable”,input);
Assert.assertEquals(tmpBean.limit_amout,input.limit_amout);
Assert.assertEquals(tmpBean.status,input.status);
}
}
}
}
由以上描述可知,本发明提供的一种测试脚本断言生成装置,装置用于执行如下步骤包括:解析目标源代码,生成所述目标源代码的数据血缘关系;根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。本申请规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
从硬件层面来说,本申请提供一种用于实现测试脚本断言生成方法中的全部或部分内容的电子设备的实施例,所述电子设备具体包含有如下内容:
图6为本申请实施例的电子设备9600的系统构成的示意框图。如图6所示,该电子设备9600可以包括中央处理器9100和存储器9140;存储器9140耦合到中央处理器9100。值得注意的是,该图6是示例性的;还可以使用其他类型的结构,来补充或代替该结构,以实现电信功能或其他功能。
在一实施例中,测试脚本断言生成功能可以被集成到中央处理器中。其中,中央处理器可以被配置为进行如下控制:
S1:解析目标源代码,生成所述目标源代码的数据血缘关系;
S2:根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。
从上述描述可知,本申请实施例提供的电子设备,规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
在另一个实施方式中,测试脚本断言生成装置可以与中央处理器9100分开配置,例如可以测试脚本断言生成装置配置为与中央处理器9100连接的芯片,通过中央处理器的控制来实现测试脚本断言生成功能。
如图6所示,该电子设备9600还可以包括:通信模块9110、输入单元9120、音频处理器9130、显示器9160、电源9170。值得注意的是,电子设备9600也并不是必须要包括图6中所示的所有部件;此外,电子设备9600还可以包括图6中没有示出的部件,可以参考现有技术。
如图6所示,中央处理器9100有时也称为控制器或操作控件,可以包括微处理器或其他处理器装置和/或逻辑装置,该中央处理器9100接收输入并控制电子设备9600的各个部件的操作。
其中,存储器9140,例如可以是缓存器、闪存、硬驱、可移动介质、易失性存储器、非易失性存储器或其它合适装置中的一种或更多种。可储存上述与失败有关的信息,此外还可存储执行有关信息的程序。并且中央处理器9100可执行该存储器9140存储的该程序,以实现信息存储或处理等。
输入单元9120向中央处理器9100提供输入。该输入单元9120例如为按键或触摸输入装置。电源9170用于向电子设备9600提供电力。显示器9160用于进行图像和文字等显示对象的显示。该显示器例如可为LCD显示器,但并不限于此。
该存储器9140可以是固态存储器,例如,只读存储器(ROM)、随机存取存储器(RAM)、SIM卡等。还可以是这样的存储器,其即使在断电时也保存信息,可被选择性地擦除且设有更多数据,该存储器的示例有时被称为EPROM等。存储器9140还可以是某种其它类型的装置。存储器9140包括缓冲存储器9141(有时被称为缓冲器)。存储器9140可以包括应用/功能存储部9142,该应用/功能存储部9142用于存储应用程序和功能程序或用于通过中央处理器9100执行电子设备9600的操作的流程。
存储器9140还可以包括数据存储部9143,该数据存储部9143用于存储数据,例如联系人、数字数据、图片、声音和/或任何其他由电子设备使用的数据。存储器9140的驱动程序存储部9144可以包括电子设备的用于通信功能和/或用于执行电子设备的其他功能(如消息传送应用、通讯录应用等)的各种驱动程序。
通信模块9110即为经由天线9111发送和接收信号的发送机/接收机9110。通信模块(发送机/接收机)9110耦合到中央处理器9100,以提供输入信号和接收输出信号,这可以和常规移动通信终端的情况相同。
基于不同的通信技术,在同一电子设备中,可以设置有多个通信模块9110,如蜂窝网络模块、蓝牙模块和/或无线局域网模块等。通信模块(发送机/接收机)9110还经由音频处理器9130耦合到扬声器9131和麦克风9132,以经由扬声器9131提供音频输出,并接收来自麦克风9132的音频输入,从而实现通常的电信功能。音频处理器9130可以包括任何合适的缓冲器、解码器、放大器等。另外,音频处理器9130还耦合到中央处理器9100,从而使得可以通过麦克风9132能够在本机上录音,且使得可以通过扬声器9131来播放本机上存储的声音。
本申请的实施例还提供能够实现上述实施例中的测试脚本断言生成方法中全部步骤的一种计算机可读存储介质,所述计算机可读存储介质上存储有计算机程序,该计算机程序被处理器执行时实现上述实施例中的执行主体为服务器或客户端的测试脚本断言生成方法的全部步骤,例如,所述处理器执行所述计算机程序时实现下述步骤:
S1:解析目标源代码,生成所述目标源代码的数据血缘关系;
S2:根据所述数据血缘关系生成一断言类,所述断言类包括一断言方法,所述断言方法用于源代码测试时被调用。
从上述描述可知,本申请实施例提供的计算机可读存储介质,规避了断言数据不准确的情况,并且通过检查断言覆盖结果保证了断言字段的全面性。
本领域内的技术人员应明白,本发明的实施例可提供为方法、装置、或计算机程序产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本发明是参照根据本发明实施例的方法、设备(装置)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
本发明中应用了具体实施例对本发明的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。
- 一种测试脚本断言生成方法及装置
- 测试脚本的自动生成方法、自动生成装置及存储介质