CN117472776A - 一种基于ast的框架自适应c++单元测试用例自动化生成方法及系统 - Google Patents
一种基于ast的框架自适应c++单元测试用例自动化生成方法及系统 Download PDFInfo
- Publication number
- CN117472776A CN117472776A CN202311587260.9A CN202311587260A CN117472776A CN 117472776 A CN117472776 A CN 117472776A CN 202311587260 A CN202311587260 A CN 202311587260A CN 117472776 A CN117472776 A CN 117472776A
- Authority
- CN
- China
- Prior art keywords
- test
- ast
- test case
- type
- case
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
- 238000012360 testing method Methods 0.000 title claims abstract description 324
- 238000000034 method Methods 0.000 title claims abstract description 70
- 238000009635 antibiotic susceptibility testing Methods 0.000 claims description 75
- 238000009826 distribution Methods 0.000 claims description 30
- 230000006870 function Effects 0.000 claims description 21
- 238000007667 floating Methods 0.000 claims description 20
- 230000008569 process Effects 0.000 claims description 14
- 238000004590 computer program Methods 0.000 claims description 9
- 230000003068 static effect Effects 0.000 claims description 9
- 238000009827 uniform distribution Methods 0.000 claims description 9
- 238000012545 processing Methods 0.000 claims description 6
- 238000004891 communication Methods 0.000 claims description 3
- 150000001875 compounds Chemical class 0.000 claims description 3
- 238000013519 translation Methods 0.000 claims description 3
- 239000003999 initiator Substances 0.000 claims description 2
- 230000003044 adaptive effect Effects 0.000 claims 2
- 238000010586 diagram Methods 0.000 description 3
- 238000005516 engineering process Methods 0.000 description 2
- 238000005192 partition Methods 0.000 description 2
- 238000013522 software testing Methods 0.000 description 2
- 125000004122 cyclic group Chemical group 0.000 description 1
- 238000002474 experimental method Methods 0.000 description 1
- 238000011990 functional testing Methods 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 238000011160 research Methods 0.000 description 1
- 230000011218 segmentation Effects 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/3668—Software testing
- G06F11/3672—Test management
- G06F11/3684—Test management for test design, e.g. generating new test cases
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/3668—Software testing
- G06F11/3672—Test management
- G06F11/3688—Test management for test execution, e.g. scheduling of test suites
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Abstract
本发明提供了一种基于AST的框架自适应C++单元测试用例自动化生成方法,解析C++项目源文件的词法和语法,生成项目的抽象语法树AST;提取AST中项目关键信息,结合测试场景需求以及测试用例设计原则,在数据类型边界值取值范围内,随机生成单元测试数据;预置GTest、CppUnit、QTest三种测试框架模板,根据测试场景头文件信息自适应选择测试框架,依据测试数据以及选定的单元测试框架模板,生成测试用例并组装头文件和具体测试用例,生成可执行的测试用例文件;基于测试框架自动执行测试用例,完成项目的单元测试。本发明提高了软件单元测试用例编写的效率,提升了对于单元测试框架的自适应能力,能够在已有测试代码的基础上进行迭代且不影响原有的测试用例。
Description
技术领域
本发明涉及软件测试技术,具体涉及一种基于AST的框架自适应C++单元测试用例自动化生成方法及系统。
背景技术
信息系统/软件的单元测试是软件研制及测试过程中的重要组成部分,也是军用软件交付前要进行的核心环节之一。随着应用系统的日益庞大以及对软件质量的要求的提升,尤其是军用软件信息系统的质量要求,对软件测试的要求越来越高,测试场景及需求越来越复杂,传统的人工测试已经不能满足复杂信息系统的测试需求。
目前,单元测试用例的编写与信息系统/软件的复杂度有很大关系,软件开发人员需要编写几倍于业务代码的单元测试代码;且编写的单元测试用例的覆盖率不达标、功能测试不充分、测试用例不兼容;不能满足复杂的测试场景需求,因此需要对复杂信息系统的源代码进行快速分析并结合测试场景需求动态生成符合要求的测试用例是目前需要解决的一个重要问题。
AST是源代码的抽象语法结构的树状表示,树上的每个节点都表示源代码中的一种结构,如变量声明、表达式、函数调用、控制结构等。树的根节点通常表示整个源代码文件,而子节点表示具体的语法元素及其关系。例如,一个函数声明的AST节点可能包含多个子节点,如函数名、参数列表和函数体等。编译器可以通过遍历AST来检查源代码中的错误,分析源代码的语义以及根据AST生成目标代码。C++单元测试用例自动生成,需要对源代码进行AST生成及分析、用例生成及组装等操作。因此,抽象语法树AST解析、用例动态生成为C++单元测试用例自动生成的主要技术。C++单元测试用例自动生成需要解决以下问题:源文件的抽象语法树AST的快速生成与解析、基于用例生成规则的用例自动生成、基于测试模板的测试执行用例的动态组装。其中,重点在于根据生成的抽象语法树进行源代码的特征信息分析,结合测试用例生成规则,确定测试数据集;再者,基于测试环境要求,结合用例组装引擎和模板,动态组装生成符合测试要求的多框架测试用例,并且能够在对应的测试环境中执行。Mao等人提出一种灵活划分的自适应随机测试用例生成方法,此方法结合了迭代分割测试和随机分区自适应随机测试的有点,不仅保证生成的测试用例具有较高随机性还保证测试用例分布均匀,同时保持与随机分区自适应随机测试的相同复杂度水平。谢肖飞等人提出一种将模糊测试与符号执行相结合的测试用例生成方法,通过模糊测试提供覆盖率信息来引导符号执行的搜索方向,从而生成更高覆盖率的测试用例,但此方法目的是发现更多的软件漏洞。
然而,上述方法主要考虑的是如何分析抽象语法树AST,并跟进抽象语法树AST生成测试数据及用例,只是在抽象语法树AST的分析及用例覆盖率上进行了进一步的研究,尚未考虑C++类软件的特殊性以及测试环境和测试场景的要求,不能根据需求动态生成组装符合特定测试场景的测试用例。
发明内容
本发明的目的在于提出一种基于AST的框架自适应C++单元测试用例自动化生成方法及系统,一方面解决复杂C++软件系统人工编写单元测试效率低、功能测试不充分、不同框架的测试用例不兼容的问题。另一方面,根据不同的测试场景/环境需求,能够实现动态组装可执行的测试用例,满足复杂的测试场景需求。
实现本发明目的的技术解决方案为:一种基于AST的框架自适应C++单元测试用例自动化生成方法,包括如下步骤:
步骤1,采用Clang编译器,解析C++项目源文件的词法和语法,生成项目的抽象语法树AST,其中词法分析阶段把文本拆成单词,通过关键字识别器、标识符识别器、常量识别器、操作符识别器确定这些单词的词性,然后生成token序列,所生成的token是一个包含单词类型type和属性值value的二元数组;语法分析阶段,通过解析器Parser根据编程语言的文法规则将上述生成的token序列组织一棵解析树,即抽象语法树AST;
步骤2,从抽象语法树AST中提取生成测试用例所需的声明节点、语句节点、类型节点,生成声明用例库、语句用例库、类型用例库,用于后续生成测试用例,其中声明节点包括类声明、函数声明和变量声明,语句节点包含条件语句、循环语句和复合语句,类型节点包含内置类型、引用类型、指针类型和数组类型;
步骤3,根据抽象语法树AST中信息获取变量的数据类型,将所有的数据类型分为四类,分别是整型、布尔型、浮点型和字符型,分别针对四种数据类型的边界值进行测试数据的随机生成;
步骤4,预置GTest、CppUnit、QTest三种不同测试框架对应的测试用例模板,根据不同测试场景头文件选择相对应的单元测试框架,依据步骤3生成的测试数据以及选定的单元测试框架模板,生成测试用例,并组装头文件和具体测试用例,生成可执行的测试用例文件;
步骤5,基于测试框架自动执行测试用例,完成项目的单元测试。
进一步的,步骤1,采用Clang编译器,解析C++项目源文件的词法和语法,生成项目的抽象语法树AST,具体方法为:
首先定义一个FunctionASTConsumer类,该类是ASTConsumer的子类,ASTConsumer是一个基类,用于处理Clang编译器生成的AST。FunctionASTConsumer类的构造函数将一个ASTContext对象作为参数,并创建一个FunctionVisitor对象,FunctionVisitor是RecursiveASTVisitor的子类。FunctionVisitor对象用于遍历AST并访问AST中的所有节点;
接着重写HandleTranslationUnit方法,并通过FunctionVisitor对象遍历翻译单元声明;
然后定义一个FunctionFrontendAction类,该类是ASTFrontendAction的子类,ASTFrontendAction是一个基类,用于在Clang编译器生成的AST上执行操作;
最后重写CreateASTConsume方法,用于创建一个FunctionASTConsumer对象,并将其作为唯一指针返回,FunctionASTConsumer对象是使用从传递的CompilerInstance对象获取的ASTContext对象创建的。
进一步的,步骤2,从抽象语法树AST中提取生成测试用例所需的声明信息、语句信息、类型信息,生成声明用例库、语句用例库、类型用例库,具体方法为:
首先对于AST三种节点,检查节点的位置是否位于宏定义中,如果是,则跳过这个节点;
接着分别获取节点的声明所在的文件名,并将其存储在名为filename的字符串中;
进一步的,检查filename是否包含被测源代码文件名,此处源代码文件名Formula.cpp,如果不包含,则跳过这个节点;
之后检查节点是否是静态方法,如果是静态方法,则输出静态方法的标识“staticmethod”,如果不是,则输出节点所属的类、命名空间信息;
然后通过“FunctionDecl”类型的对象获取函数声明信息,通过“RecursiveASTVisitor”的成员函数VisitStmt获取语句信息,通过“QualType”类型的对象获取类型信息。
最终输出节点的信息,包括声明信息、语句信息、类型信息。
进一步的,步骤3,根据抽象语法树AST中信息获取变量的数据类型,将所有的数据类型分为四类,分别是整型、布尔型、浮点型和字符型,分别针对四种数据类型的边界值进行测试数据的随机生成,其中:
对于整型变量,首先使用<random>头文件中的std::random_device作为随机数生成器的种子,然后使用MersenneTwister引擎std::mt19937来生成随机数,之后使用std::numeric_limits获取整型的最小值、最大值取值范围,通过std::uniform_int_distribution定义整数分布在最值范围内,最终通过调用distribution(gen)生成随机整数;
对于布尔型变量,使用std::random_device作为种子,std::default_random_engine作为随机数引擎,接着使用std::bernoulli_distribution定义伯努利分布,表示生成bool值的概率为0.5,std::bernoulli_distribution返回一个符合该分布的随机值,最后随机生成true和false两种数据;
对于浮点型变量,std::uniform_real_distribution<double>定义了一个浮点数均匀分布,其范围由浮点数最大最小值指定,浮点数最大值为3.4028235e+38,最小值为1.4e-45,最后调用distribution(gen),在取值范围内随机生成1组浮点数测试数据;对于字符型变量,定义字符变量取值范围为A-Z,使用std::uniform_int_distribution<int>定义一个整数均匀分布,其范围由min_char=A和max_char=Z指定,然后通过static_cast<char>(distribution(gen))将生成的整数转换为字符。
进一步的,步骤4,预置GTest、CppUnit、QTest三种不同测试框架对应的测试用例模板,根据不同测试场景头文件选择相对应的单元测试框架,依据步骤3生成的测试数据以及选定的单元测试框架模板,生成测试用例,并组装头文件和具体测试用例,生成可执行的测试用例文件,具体方法为:
首先分别预置三种不同测试框架对应的测试用例模板,测试用例模板中包含对应测试框架的头文件、具体的测试用例条目、测试断言语句;
其次依据测试场景自动选择不同的单元测试框架,过程如下:首先定义一种用于处理一组相关联声明的数据结构DeclGroupRef,迭代DeclGroupRef中的每个声明,通过类型检查dyn_cast<IncludeDirective>()判断是否是头文件引用,如果是,则输出头文件信息,否则跳过本次判断;然后依据头文件信息判断头文件是否包含Qt框架,如果包含则选择QTest测试框架,否则继续判断是否包含网络通信库或数据库连接库或调用web服务的库,如果包含,则选择使用GTest测试框架,否则按照GTest和CppUnit各0.5概率随机选择测试框架;
最后将步骤3中的测试数据填写到具体的测试用例条目和断言语句中,完成测试用例生成,将头文件和具体的测试用例条目以及断言语句组装到一个测试用例文件中,生成针对特定测试框架的测试用例文件,完成测试用例的组装。
进一步的,步骤5,根据测试场景及测试框架需求,调用不同的测试框架代码,执行上述测试用例文件,收集测试用例执行结果,最终生成测试用例执行报告。
一种基于AST的框架自适应C++单元测试用例自动化生成系统,实施所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述处理器执行所述计算机程序时,实施所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时,实施所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
本发明与现有技术相比,其显著优点为:(1)通过C++单元测试用例自动生成,降低了软件开发人员的投入的成本,能够有效提升软件开发人员单元测试用例编写的效率。(2)根据测试框架需求,自动生成对应测试框架样式的测试用例,根据用例生成规则自动生成不同类型测试用例数据,实现测试用例框架自适应,提高了单元测试用例适用范围。(3)根据测试环境要求及测试场景,动态组装生成可执行的测试用例,提升了测试用例的适应性和执行效率。
附图说明
图1是本发明的总体流程图;
图2是本发明的生成并获取抽象语法树AST过程图;
图3是本发明的解析并提取AST信息过程图;
图4为本发明的测试用例动态组装图。
具体实施方式
为了使本申请的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本申请进行进一步详细说明。应当理解,此处描述的具体实施例仅仅用以解释本申请,并不用于限定本申请。
如图1所示,本发明提出一种基于AST的框架自适应C++单元测试用例自动化生成方法,包括如下步骤:
步骤1,获取C++源代码,其中,每对.h和.cpp文件构成一个编译单元(TranslationUnit)。
步骤2,采用Clang编译器编译C++源码,编译过程中经词法分析、语法分析后生成抽象语法树AST。词法分析器读取源代码,识别各个单词,并将识别出的单词转换为统一的机内表示——词法单元(Token)形式,同时,它会移除空白符、注释等。最后,整个代码将被分割进一个token数组。语法分析会将词法分析出来的数组转换成树形的结构,同时会验证语法的正确性,最终构建成为AST形式。编译主要流程如图2所示。
步骤3,对生成的AST进行遍历和分析,提取关键信息。Clang编译生成的AST主要包含三种节点:声明节点Decl,包括变量、函数、类、命名空间等的声明以及头文件信息;语句节点Stmt,包括条件语句、循环语句、复合语句等;类型节点Expr,包括内置类型、引用类型、指针类型、数组类型等。从中提取生成测试用例所需的声明信息、语句信息、类型信息,并生成声明用例库、语句用例库、类型用例库,用于后续生成测试用例,具体如图3所示。AST的所有信息都打包进了ASTContext,因此需要自顶向下来对AST进行递归遍历,调用RecursiveASTVisitor这个API就可以提取AST中的信息。
三种节点提取信息的过程是一致的。首先检查节点的位置是否位于宏定义中,如果是,则跳过这个节点,因为宏定义中的节点通常不需要处理。接着获取节点所在的文件名,如果节点所在的文件名不包含源代码文件名,则跳过这个节点。之后检查节点是否是静态方法,如果是,则输出“staticmethod”,否则跳过本次判断,并获取节点所属的类和命名空间信息。然后通过“FunctionDecl”类型的对象获取函数声明信息,通过“RecursiveASTVisitor”的成员函数VisitStmt获取语句信息,通过“QualType”类型的对象获取类型信息。最终输出节点的信息,包括声明信息、语句信息、类型信息。将三种节点信息分别存储进入声明用例库、语句用例库、类型用例库。
步骤4,在数据类型边界值取值范围内,随机生成单元测试数据。详细过程如下:根据AST中信息获取变量的数据类型,将所有的数据类型分为四类,分别是整型、布尔型、浮点型和字符型,分别针对四种数据类型进行测试用例数据生成。其中,对于整型变量,首先使用<random>头文件中的std::random_device作为随机数生成器的种子,然后使用MersenneTwister引擎std::mt19937来生成随机数,之后使用std::numeric_limits获取整型的最小值、最大值取值范围,通过std::uniform_int_distribution定义整数分布在最值范围内,最终通过调用distribution(gen)生成随机整数;对于布尔型变量,使用std::random_device作为种子,std::default_random_engine作为随机数引擎,接着使用std::bernoulli_distribution定义伯努利分布,表示生成bool值的概率为0.5,std::bernoulli_distribution返回一个符合该分布的随机值,最后随机生成true和false两种数据;对于浮点型变量,std::uniform_real_distribution<double>定义了一个浮点数均匀分布,其范围由浮点数最大最小值指定,浮点数最大值为3.4028235e+38,最小值为1.4e-45,最后调用distribution(gen),在取值范围内随机生成1组浮点数测试数据;对于字符型变量,定义字符变量取值范围为A-Z,使用std::uniform_int_distribution<int>定义一个整数均匀分布,其范围由min_char=A和max_char=Z指定,然后通过static_cast<char>(distribution(gen))将生成的整数转换为字符。
步骤5,根据测试场景需求,利用步骤3中提取的信息,选择不同测试框架,并选择对应测试框架的单元测试用例模板。然后根据步骤4生成的测试数据,按照测试框架模板生成对应不同测试框架的测试用例。具体步骤如下:
(1)首先分别预置三种不同测试框架(GTest、CppUnit、QTest)对应的测试用例模板。测试用例模板中包含对应测试框架的头文件、具体的测试用例条目、测试断言语句。其中,对于GTest,头文件是<gtest/gtest.h>,具体的测试用例条目和断言语句格式是:
TEST(TestSuiteName,TestName){
ASSERT_EQ(expected,actual);
}
对于CppUnit,头文件包含<cppunit/extensions/HelperMacros.h>、<cppunit/TestSuite.h>和<cppunit/ui/text/TestRunner.h>,具体的测试用例条目和断言语句格式是:
对于QTest,头文件包含<QtTest/QtTest>,具体的测试用例条目和断言语句格式是:
voidtestMethod(){
QVERIFY(someCondition);
QCOMPARE(expected,actual);
(2)其次依据测试场景自动选择不同的单元测试框架。选择测试框架的过程如下:首先通过步骤3中获取到的源代码AST,定义一种用于处理一组相关联声明的数据结构DeclGroupRef,然后迭代DeclGroupRef中的每个声明,通过类型检查dyn_cast<IncludeDirective>()判断是否是头文件引用,如果是,则获取并输出头文件名,否则跳过本次判断。之后判断头文件名是否包含Qt框架,即<QCoreApplication>、<QApplication>、<QPainter>,如果包含,则直接选择QTest测试框架;如果不包含,继续判断头文件名是否包含网络通信库<.*socket.*\.h>或数据库连接库<.*sql.*\.h>或调用web服务的库<.*curl.*\.h>和<.*http.*\.h>,如果包含,则选择使用GTest测试框架,因为GTest特别适用于有依赖其他模块的项目;如果不包含上述库,则按照GTest和CppUnit各0.5概率随机选择测试框架。当选定某一个测试框架之后,会调用对应测试框架模板继续完成后续操作。
(3)最后根据步骤4中生成的测试数据生成测试用例。将步骤4中的测试数据填写到具体的测试用例条目和断言语句中。其中,expected填写通过实际运算获得的结果,actual填写通过运行源程序函数生成的结果。
步骤6,将步骤5中生成的头文件和具体的测试用例条目以及断言语句组装到一个测试用例文件中,生成针对特定测试框架的测试用例文件,完成测试用例的组装。
具体来说,首先根据步骤5从AST中获取到的头文件信息,组装测试用例文件头文件部分,头文件部分包含被测源代码的头文件、测试框架头文件。接着组装具体的测试用例条目以及断言语句。完成测试用例的动态组装工作。测试用例文件动态组装结构如图4所示。
步骤7,根据测试场景及测试框架需求,调用不同的测试框架代码,执行步骤6中组装生成的测试用例文件,收集测试用例执行结果,最终生成测试用例执行报告。
具体来说,根据测试场景及测试框架需求,调用不同的测试框架代码,编译对应的测试框架。接着自动编译并执行上述步骤生成的测试用例文件。执行过程可以根据不同测试框架加入相应参数,然后收集测试用例执行结果,最终调用对应测试框架测试报告模板,生成测试用例执行报告。
本发明还提出一种基于AST的框架自适应C++单元测试用例自动化生成系统,实施所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述处理器执行所述计算机程序时,实施所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时,实施所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
实施例
为了验证本发明方案的有效性,进行如下实验。
本发明提供了一种框架自适应的C++单元测试用例自动生成方法,实现C++项目软件代码的单元测试用例的自动生成及测试框架自适应。为了方便描述,我们假定有如下简化的应用实例。
根据我们前面提到的步骤,依次实施:
步骤1)获取C++源代码,其中,每对.h和.cpp文件构成一个编译单元(TranslationUnit)。本实例中,编译单元为Formula.h和Formula.cpp。
其中,Formula.h代码如下:
步骤2)采用Clang编译器编译C++源码,编译过程中经词法分析、语法分析后生成抽象语法树AST,并获取AST。具体实施过程如下:
(1)首先定义一个FunctionASTConsumer类,该类是ASTConsumer的子类,ASTConsumer是一个基类,用于处理Clang编译器生成的AST。FunctionASTConsumer类的构造函数将一个ASTContext对象作为参数,并创建一个FunctionVisitor对象,FunctionVisitor是RecursiveASTVisitor的子类。FunctionVisitor对象用于遍历AST并访问AST中的所有节点。实现代码如下:
(2)接着重写HandleTranslationUnit方法,并通过FunctionVisitor对象遍历翻译单元声明。实现代码如下:
virtualvoidHandleTranslationUnit(ASTContext&Context){
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
}
(3)然后定义一个FunctionFrontendAction类,该类是ASTFrontendAction的子类,ASTFrontendAction是一个基类,用于在Clang编译器生成的AST上执行操作。实现代码如下:
classFunctionFrontendAction:publicASTFrontendAction{}
(4)接着重写CreateASTConsume方法,用于创建一个FunctionASTConsumer对象,并将其作为唯一指针返回。FunctionASTConsumer对象是使用从传递的CompilerInstance对象获取的ASTContext对象创建的。实现代码如下:
步骤3)对生成的AST进行遍历和分析,并从中提取生成测试用例所需的函数名、返回类型、参数类型等信息。如图3所示。然后输出与这些函数相关的信息。最后将三种节点信息分别存储进入声明用例库、语句用例库、类型用例库,用于生成测试用例。具体过程如下:
(1)首先对于AST三种节点,检查节点的位置是否位于宏定义中,如果是,则跳过这个节点。实现伪代码如下:
(2)接着分别获取三种节点的声明所在的文件名,并将其存储在名为filename的字符串中。实现伪代码如下:
filename=Context->getSourceManager();//获取三种节点的位置所在的文件名;
(3)进一步的,检查filename是否包含被测源代码文件名,此处源代码文件名Formula.cpp。如果不包含,则跳过这个节点。实现伪代码如下:
if(filename.find("Formula.cpp")==std::string::npos){
returntrue;
}
(4)之后检查节点是否是静态方法,并判断方法所属的类、命名空间等信息。实现伪代码如下:
if(方法->静态方法()){
输出“staticmethod”
}
if(类、命名空间=dyn_cast<C++记录、命名空间>(方法、类的父级声明)
(5)最终输出与这些函数相关的信息,包括声明信息、语句信息、类型信息。实现伪代码如下:
std::cout<<"声明信息、语句信息、类型信息"<<FD->getNameAsString()<<
std::endl;
步骤4)进行测试数据生成。具体取值范围如下:
步骤5)根据测试场景及测试框架(例如GTest、CppUnit、QTest等)需求,利用步骤3)中提取的信息以及步骤4)中的测试数据,自动选择测试框架,并生成对应不同测试框架的多种形式的测试用例。具体过程如下:
(1)首先分别预置三种不同测试框架(GTest、CppUnit、QTest)对应的测试用例模板。测试用例模板中包含对应测试框架的头文件、具体的测试用例条目、测试断言语句。
(2)其次依据测试场景自动选择不同的单元测试框架。实现伪代码如下:
//通过迭代DeclGroupRef,检查是否有头文件引用
(3)最后根据步骤4中生成的测试数据生成测试用例。将步骤4中的测试数据填写到具体的测试用例条目和断言语句中。其中,expected填写通过实际运算获得的结果,actual填写通过运行源程序函数生成的结果。
实现伪代码如下:
file<<"ASSERT_EQ(期望结果,"<<classDecl->getNameAsString()+"::"+
FD->getNameAsString()");\n";
步骤6)将步骤5中生成的头文件和具体的测试用例条目以及断言语句组装到一个测试用例文件中,生成针对特定测试框架的测试用例文件,完成测试用例的组装。实现伪代码如下:
//以追加方式打开文件
std::ofstreamfile(testFilePath,std::ios::app);
//写入头文件、测试用例
file<<"#include\"写入被测源代码的头文件、测试框架头文件\"\n";
file<<"//写入具体的测试用例条目以及断言语句\n";
//关闭文件
file.close();
步骤7)根据测试场景及测试框架需求,调用不同的测试框架代码,执行步骤5)中生成的测试用例文件,收集测试用例执行结果,最终生成测试用例执行报告。实现伪代码如下:
//编译测试框架及测试用例文件
make
//执行测试用例,生成测试报告
./可执行文件.exe–输出测试报告格式=xml。
综上所述,本发明除了针对性地考虑C++类项目单元测试用例编写的语法特点和应用场景外,还结合测试用例生成规则,实现测试框架自适应的C++单元测试用例自动生成;并基于上述的单元测试用例组装引擎和模板,动态组装生成符合测试要求的多框架测试用例,提升用例的适应性和执行效率。
以上实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。
以上所述实施例仅表达了本申请的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对本申请范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本申请构思的前提下,还可以做出若干变形和改进,这些都属于本申请的保护范围。因此,本申请的保护范围应以所附权利要求为准。
Claims (9)
1.一种基于AST的框架自适应C++单元测试用例自动化生成方法,其特征在于,包括如下步骤:
步骤1,采用Clang编译器,解析C++项目源文件的词法和语法,生成项目的抽象语法树AST,其中词法分析阶段把文本拆成单词,通过关键字识别器、标识符识别器、常量识别器、操作符识别器确定这些单词的词性,然后生成token序列,所生成的token是一个包含单词类型type和属性值value的二元数组;语法分析阶段,通过解析器Parser根据编程语言的文法规则将上述生成的token序列组织一棵解析树,即抽象语法树AST;
步骤2,从抽象语法树AST中提取生成测试用例所需的声明节点、语句节点、类型节点,生成声明用例库、语句用例库、类型用例库,用于后续生成测试用例,其中声明节点包括类声明、函数声明和变量声明,语句节点包含条件语句、循环语句和复合语句,类型节点包含内置类型、引用类型、指针类型和数组类型;
步骤3,根据抽象语法树AST中信息获取变量的数据类型,将所有的数据类型分为四类,分别是整型、布尔型、浮点型和字符型,分别针对四种数据类型的边界值进行测试数据的随机生成;
步骤4,预置GTest、CppUnit、QTest三种不同测试框架对应的测试用例模板,根据不同测试场景头文件选择相对应的单元测试框架,依据步骤3生成的测试数据以及选定的单元测试框架模板,生成测试用例,并组装头文件和具体测试用例,生成可执行的测试用例文件;
步骤5,基于测试框架自动执行测试用例,完成项目的单元测试。
2.根据权利要求1所述的基于AST的框架自适应C++单元测试用例自动化生成方法,其特征在于,步骤1,采用Clang编译器,解析C++项目源文件的词法和语法,生成项目的抽象语法树AST,具体方法为:
首先定义一个FunctionASTConsumer类,该类是ASTConsumer的子类,ASTConsumer是一个基类,用于处理Clang编译器生成的AST。FunctionASTConsumer类的构造函数将一个ASTContext对象作为参数,并创建一个FunctionVisitor对象,FunctionVisitor是RecursiveASTVisitor的子类。FunctionVisitor对象用于遍历AST并访问AST中的所有节点;
接着重写HandleTranslationUnit方法,并通过FunctionVisitor对象遍历翻译单元声明;
然后定义一个FunctionFrontendAction类,该类是ASTFrontendAction的子类,ASTFrontendAction是一个基类,用于在Clang编译器生成的AST上执行操作;
最后重写CreateASTConsume方法,用于创建一个FunctionASTConsumer对象,并将其作为唯一指针返回,FunctionASTConsumer对象是使用从传递的CompilerInstance对象获取的ASTContext对象创建的。
3.根据权利要求1所述的基于AST的框架自适应C++单元测试用例自动化生成方法,其特征在于,步骤2,从抽象语法树AST中提取生成测试用例所需的声明信息、语句信息、类型信息,生成声明用例库、语句用例库、类型用例库,具体方法为:
首先对于AST三种节点,检查节点的位置是否位于宏定义中,如果是,则跳过这个节点;
接着分别获取节点的声明所在的文件名,并将其存储在名为filename的字符串中;
进一步的,检查filename是否包含被测源代码文件名,此处源代码文件名Formula.cpp,如果不包含,则跳过这个节点;
之后检查节点是否是静态方法,如果是静态方法,则输出静态方法的标识“staticmethod”,如果不是,则输出方法所属的类、命名空间信息;
然后通过“FunctionDecl”类型的对象获取函数声明信息,通过“RecursiveASTVisitor”的成员函数VisitStmt获取语句信息,通过“QualType”类型的对象获取类型信息。
最终输出节点的信息,包括声明信息、语句信息、类型信息。
4.根据权利要求1所述的基于AST的框架自适应C++单元测试用例自动化生成方法,其特征在于,步骤3,根据抽象语法树AST中信息获取变量的数据类型,将所有的数据类型分为四类,分别是整型、布尔型、浮点型和字符型,分别针对四种数据类型的边界值进行测试数据的随机生成,其中:
对于整型变量,首先使用<random>头文件中的std::random_device作为随机数生成器的种子,然后使用Mersenne Twister引擎std::mt19937来生成随机数,之后使用std::numeric_limits获取整型的最小值、最大值取值范围,通过std::uniform_int_distribution定义整数分布在最值范围内,最终通过调用distribution(gen)生成随机整数;
对于布尔型变量,使用std::random_device作为种子,std::default_random_engine作为随机数引擎,接着使用std::bernoulli_distribution定义伯努利分布,表示生成bool值的概率为0.5,std::bernoulli_distribution返回一个符合该分布的随机值,最后随机生成true和false两种数据;
对于浮点型变量,std::uniform_real_distribution<double>定义了一个浮点数均匀分布,其范围由浮点数最大最小值指定,浮点数最大值为3.4028235e+38,最小值为1.4e-45,最后调用distribution(gen),在取值范围内随机生成1组浮点数测试数据;对于字符型变量,定义字符变量取值范围为A-Z,使用std::uniform_int_distribution<int>定义一个整数均匀分布,其范围由min_char=A和max_char=Z指定,然后通过static_cast<char>(distribution(gen))将生成的整数转换为字符。
5.根据权利要求1所述的基于AST的框架自适应C++单元测试用例自动化生成方法,其特征在于,步骤4,预置GTest、CppUnit、QTest三种不同测试框架对应的测试用例模板,根据不同测试场景头文件选择相对应的单元测试框架,依据步骤3生成的测试数据以及选定的单元测试框架模板,生成测试用例,并组装头文件和具体测试用例,生成可执行的测试用例文件,具体方法为:
首先分别预置三种不同测试框架对应的测试用例模板,测试用例模板中包含对应测试框架的头文件、具体的测试用例条目、测试断言语句;
其次依据测试场景自动选择不同的单元测试框架,过程如下:首先定义一种用于处理一组相关联声明的数据结构DeclGroupRef,迭代DeclGroupRef中的每个声明,通过类型检查dyn_cast<IncludeDirective>()判断是否是头文件引用,如果是,则输出头文件信息,否则跳过本次判断;然后依据头文件信息判断头文件是否包含Qt框架,如果包含则选择QTest测试框架,否则继续判断是否包含网络通信库或数据库连接库或调用web服务的库,如果包含,则选择使用GTest测试框架,否则按照GTest和CppUnit各0.5概率随机选择测试框架;
最后将步骤3中的测试数据填写到具体的测试用例条目和断言语句中,完成测试用例生成,将头文件和具体的测试用例条目以及断言语句组装到一个测试用例文件中,生成针对特定测试框架的测试用例文件,完成测试用例的组装。
6.根据权利要求1所述的基于AST的框架自适应C++单元测试用例自动化生成方法,其特征在于,步骤5,根据测试场景及测试框架需求,调用不同的测试框架代码,执行上述测试用例文件,收集测试用例执行结果,最终生成测试用例执行报告。
7.一种基于AST的框架自适应C++单元测试用例自动化生成系统,其特征在于,实施权利要求1-6任一项所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
8.一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述处理器执行所述计算机程序时,实施权利要求1-6任一项所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
9.一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时,实施权利要求1-6任一项所述的基于AST的框架自适应C++单元测试用例自动化生成方法,实现单元测试用例自动化生成。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202311587260.9A CN117472776A (zh) | 2023-11-24 | 2023-11-24 | 一种基于ast的框架自适应c++单元测试用例自动化生成方法及系统 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202311587260.9A CN117472776A (zh) | 2023-11-24 | 2023-11-24 | 一种基于ast的框架自适应c++单元测试用例自动化生成方法及系统 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN117472776A true CN117472776A (zh) | 2024-01-30 |
Family
ID=89623866
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202311587260.9A Pending CN117472776A (zh) | 2023-11-24 | 2023-11-24 | 一种基于ast的框架自适应c++单元测试用例自动化生成方法及系统 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN117472776A (zh) |
-
2023
- 2023-11-24 CN CN202311587260.9A patent/CN117472776A/zh active Pending
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN112100054B (zh) | 一种面向数据管控的程序静态分析方法和系统 | |
CN111708539B (zh) | 一种应用程序代码转换方法、装置、电子设备和存储介质 | |
Beazley | Automated scientific software scripting with SWIG | |
US8813047B2 (en) | Yet another transformation language (YATL) | |
US7958493B2 (en) | Type inference system and method | |
US5860011A (en) | Method and system for automatically checking computer source code quality based on rules | |
CN108614707A (zh) | 静态代码检查方法、装置、存储介质和计算机设备 | |
US20070028222A1 (en) | Free/outer variable capture | |
US8806452B2 (en) | Transformation of computer programs and eliminating errors | |
US20090144229A1 (en) | Static query optimization for linq | |
US20070044083A1 (en) | Lambda expressions | |
US20020100022A1 (en) | Method and apparatus for automatic verification of properties of a concurrent software system | |
CN109491658A (zh) | 计算机可执行代码数据的生成方法及装置 | |
US20130152061A1 (en) | Full fidelity parse tree for programming language processing | |
US20070074185A1 (en) | Identifier expressions | |
CN108563561B (zh) | 一种程序隐性约束提取方法及系统 | |
CN108595334B (zh) | 一种计算Java程序动态切片的方法、装置及可读存储介质 | |
Tassi | Deriving proved equality tests in Coq-elpi: Stronger induction principles for containers in Coq | |
CN113157597A (zh) | 结构解析方法、装置、电子设备和存储介质 | |
CN111381828A (zh) | 生成代码文件的语法树的方法、装置及电子设备 | |
US10642714B2 (en) | Mapping dynamic analysis data to source code | |
RU2115158C1 (ru) | Способ и устройство для достоверной оценки семантических признаков в синтаксическом анализе при проходе вперед слева направо | |
Fritzson et al. | Metamodelica–a symbolic-numeric modelica language and comparison to julia | |
CN111858322A (zh) | 一种Python语言特征自动识别系统和方法 | |
CN111381826A (zh) | 生成代码文件的语法树的方法、装置及电子设备 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination |