基于覆盖率量化指标确定软件测试过程充分性的方法

文档序号:6437032阅读:337来源:国知局
专利名称:基于覆盖率量化指标确定软件测试过程充分性的方法
技术领域
本发明涉及软件测试技术,尤其涉及一种基于覆盖率量化指标确定软件测试过程充分性的方法,即利用代码覆盖率作为量化指标来确定软件测试中的测试是否充分。
背景技术
在软件单元测试的各个阶段中,人们总是期望用一个统一的量化指标来确定测试过程和方法的充分性,并以此来指导何时结束测试。这里,覆盖率是软件单元测试中常见的量化评价标准,常见的覆盖准则包括语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、修改的判定条件覆盖、组合覆盖以及路径覆盖等。但,现有的传统覆盖准则,并不适用于软件测试的各个阶段。所述测试阶段,包括单元测试、集成测试和系统测试。另外,传统的覆盖准则也有待进一步扩展,以解决软件测试技术发展过程中的新问题。

发明内容
有鉴于此,本发明的主要目的在于提供一种基于覆盖率量化指标确定软件测试过程充分性的方法,扩展传统覆盖准则的使用阶段,以适用评估不同测试阶段中的多种动态测试方法;并扩展传统单元测试的覆盖准则,提出文件覆盖、方法覆盖和类覆盖等新的准则;以及能够按照给定的覆盖准则,对被测单元进行静态分析,得到待覆盖元素集合,根据用户测试需求,进行动态测试执行,统计被覆盖元素,并计算覆盖率,从而根据覆盖率量化指标来确定软件测试过程和方法的充分性,使用多种覆盖准则统计的覆盖率进行衡量,提高评估测试的效率和准确性。为达到上述目的,本发明的技术方案是这样实现的
一种基于覆盖率量化指标确定软件测试过程充分性的方法,该方法主要包括
A、对被测程序进行预编译、词法分析和语法分析,得到程序的抽象语法树、控制流图和函数之间的调用关系图,并根据用户测试需求,自动生成被测单元;
B、根据覆盖准则,从所述抽象语法树和控制流图中提取被测单元中相应的待覆盖元素集合;
C、根据所述的覆盖准则,在被测单元的程序中插入相应的探针函数;
D、根据用户测试需求,选择系统自动执行或用户手动执行的方式对插入探针函数的被测单元进行动态测试;
E、根据动态测试执行的返回信息,得到测试单元的被覆盖元素集合,并计算被测单元
的覆盖率。其中,所述步骤A包括
根据被测程序中的函数调用关系,对被测程序进行单元划分,得到被测单元;所述被测单元为根据用户测试需求,将被测试程序划分成的独立的测试对象,其为一个或多个函数、 类、文件。所述步骤B包括对于语句覆盖准则,提取被测试单元的函数中每一个可达语句块作为语句覆盖元素, 组成语句覆盖元素集合;
对于分支覆盖准则,提取被测试单元的函数中,每一个可达分支作为分支覆盖元素,组成分支覆盖元素集合;
对于C/DC覆盖准则,提取被测试单元的函数中,每个覆盖元素包括可被执行的判定表达式;判定表达式中,所有取值既可以为真又可以为假的简单条件,由此遍历整个被测单元,组成C/DC覆盖元素集合;
对于MC/DC覆盖准则,提取被测试单元的函数中,每个覆盖元素包括可被执行的判定表达式;判定表达式中,所有可以独立影响判定表达式结果的简单条件,由此遍历整个被测单元,组成MC/DC覆盖元素集合;
对于路径覆盖准则,提取被测试单元的函数中,所有可达路径作为覆盖元素,组成路径覆盖元素集合;
对于函数覆盖准则,提取被测试单元的类(对于函数直接构成类的情况)或者文件(对于函数直接构成文件的情况)中,所有可被执行的函数作为函数覆盖元素,组成函数覆盖元素集合;假设函数中只要有一条路径可被执行,就认为该函数可被执行;
对于类覆盖准则,提取被测试单元的文件中所有可被执行的类作为类覆盖元素,构成类覆盖元素集合;
对于文件覆盖准则,提取被测试单元中所有可被执行的文件作为文件覆盖元素,组成文件覆盖元素集合;对于由类直接组成文件的情况,该文件中只要有一个类可被执行,就认为该文件可被执行;对于由函数直接组成文件的情况,该文件中只要有一个函数可被执行, 就认为该文件可被执行。所述步骤C包括
对于语句覆盖准则,在语句覆盖元素集合的每个元素中插入探针函数,以便记录执行测试用例过程中语句块的被覆盖情况;
对于分支覆盖准则,在分支覆盖元素集合每个元素中插入分支探针函数,以便记录执行测试用例过程中分支的被覆盖情况;
对于C/DC覆盖准则,在C/DC覆盖元素集合的每个元素中插入探针函数,即在每个可执行判定中插入分支探针函数,在对应判定中所有取值既可以为真又可以为假的简单条件处插入条件探针函数,以便记录执行测试用例过程中C/DC元素的被覆盖情况;
对于MC/DC覆盖准则,在MC/DC覆盖元素集合中的每个元素内插入探针函数;即在每个可执行判定处插入分支探针函数,在对应判定中的所有可独立影响判定的简单条件处插入条件探针函数,以便记录执行测试用例过程中MC/DC元素的被覆盖情况;
对于路径覆盖准则,基于语句覆盖进行统计,所以不用额外插入探针函数; 对于函数覆盖准则,基于路径覆盖进行统计,所以不用额外插入探针函数; 对于类覆盖准则,基于函数覆盖进行统计,所以不用额外插入探针函数; 对于文件覆盖准侧,基于类或者函数覆盖进行统计,所以不用额外插入探针函数。所述步骤D包括
对于系统自动执行,系统自动生成被测单元的测试用例,生成驱动文件,逐个调用测试用例,将驱动文件和插入探针函数之后的被测单元所在文件链接生成可执行文件,然后运行可执行文件,进行测试执行;
对于用户手动执行,由用户手动对预处理后的待测程序生成可能的桩函数、测试用例和驱动文件,并将驱动文件和所述的插入探针函数之后的被测单元所在文件进行链接,生成可执行文件并运行,进行测试执行。所述步骤E具体包括
E1、利用被测试程序的探针函数的返回信息,得到被覆盖元素集合; E2、分析覆盖结果,通过图形界面的方式标识出源代码中已覆盖元素和未覆盖元素,并计算出被测单元的语句覆盖率、分支覆盖率、C/DC覆盖率、MC/DC覆盖率、路径覆盖率、函数覆盖率、类覆盖率、文件覆盖率。进一步地,所述步骤El包括
E11、对于语句覆盖准则,探针函数返回测试过程中被测单元语句覆盖集合的所有被覆盖语句块对应的数字;
E12、对于分支覆盖准则,探针函数返回测试过程中被测单元分支覆盖集合的所有被覆盖的分支对应的数字;
E13、对于C/DC覆盖准则,探针函数返回测试过程中被测单元C/DC覆盖集合的被覆盖元素(所有被覆盖的判定以及判定中所有被覆盖的简单条件)对应的数字;
E14、对于MC/DC覆盖准则,探针函数返回测试过程中被测单元MC/DC覆盖集合的被覆盖元素(所有被覆盖的判定,以及判定中所有被覆盖的可独立影响判定的简单条件)对应的数字;
E15、对于路径覆盖准则,根据步骤Ell中获得的语句覆盖集合的被覆盖语句块,按照一条路径被覆盖当且仅当此路径上的所有语句块被覆盖的原则,提取出被测试单元的所有被覆盖路径;
E16、对于函数覆盖准则,根据步骤E15中获得的路径覆盖集合中被覆盖路径,按照一个函数被覆盖当且仅当此函数中至少有一条路径被覆盖的原则,提取出被测试类的所有被覆盖函数(对于文件直接由类构成的情况)或文件中的所有被覆盖函数(对于文件直接由函数构成的情况);
E17、对于类覆盖准则,根据步骤E16中获得的被覆盖函数,按照一个类被覆盖当且仅当此类中至少有一个函数被覆盖的原则,提取出被测试文件的所有被覆盖类;
E18、对于文件覆盖准则,如果文件直接由类构成,根据步骤E17中获得的被覆盖类,按照一个文件被覆盖当且仅当此文件中至少有一个类被覆盖的原则,或者根据E16中获得的被覆盖函数,按照一个文件被覆盖当且仅当此文件中至少有一个函数被覆盖的原则,提取出被测试工程的所有被覆盖文件。本发明所提供的基于覆盖率量化指标确定软件测试过程充分性的方法,具有以下优点
该方法一方面扩展了传统覆盖率的使用阶段,适用于评估不同测试阶段中的多种动态测试方法,测试阶段包括单元测试、集成测试和系统测试;另一方面扩展了传统单元测试的覆盖准则,提出文件覆盖、方法覆盖和类覆盖等准则。并能够按照给定的覆盖准则,对被测单元进行静态分析,得到待覆盖元素集合,也能够根据用户测试需求,进行动态测试执行, 统计被覆盖元素,并计算覆盖率,从而能够根据覆盖率量化指标来确定软件测试过程和方法的充分性,通过使用多种覆盖准则统计的覆盖率进行衡量,提高了评估测试的效率和准确性。


图1为本发明基于覆盖率量化指标确定软件测试过程充分性的方法流程示意图; 图2为本发明软件测试过程进行自动单元划分的方法流程示意图3为本发明软件测试过程进行自动测试执行的方法流程示意图。
具体实施例方式下面结合附图及本发明的实施例对本发明的方法作进一步详细的说明。白盒自动化软件测试中多种覆盖率的统一计算方法可以采用不同的测试工具及测试方法动态执行被测程序,本发明提供的确定软件测试过程充分性的方法,是一种借助自动化软件测试的覆盖率作为量化指标来确定所进行的软件测试过程是否充分的手段,其基本思想是读取待测程序,对其进行静态分析,根据用户测试需求,将被测程序划分成测试单元。其中,当选择系统自动执行时,系统将单个函数作为一个被测单元,当选择人工手动执行时,由用户选择需要测试的一个或多个函数、类或者文件,系统将其作为一个被测单元。然后由用户选择覆盖准则,根据生成的被测单元的抽象语法树和控制流图,提取待覆盖的元素集合,对被测单元的程序插入相应的探针函数,可采用自动和人工两种方式进行动态测试执行,根据执行返回结果,得到被覆盖元素,进而计算出被测单元的覆盖率。图1为本发明基于覆盖率量化指标确定软件测试过程充分性的方法流程示意图, 如图1所示,主要包括如下步骤
步骤1、对被测程序进行预编译、词法分析和语法分析,得到程序的抽象语法树、控制流图和函数之间的调用关系图,并根据用户测试需求,自动生成被测单元。所述步骤1,具体包括
步骤11、根据被测程序中的函数调用关系,对被测程序进行单元划分,得到被测单元。所述被测单元是指根据用户测试需求,将被测试程序划分成的独立的测试对象, 可以是一个或多个函数、类、文件等。被测工程以被测单元为单位进行划分,采用自动划分时,单个的函数作为一个被测单元,采用人工干预划分时,由用户指定每个被测单元的组成,可以是若干个函数、类、文件,或者它们的任意组合。所述步骤11进一步包括
步骤111、自动划分时,系统将单个的函数作为一个被测单元。自动单元划分的流程示意图,如图2所示
以被测程序S为例,其包含3个函数fl(typel vl),f2(type2 v2), f 3 (type3 v3), typel、type2、type3为参数类型,对其进行静态分析后,得到函数调用关系,提取每个函数的输入和输出,将每一个有输入的函数作为一个被测单元,由此可知,自动划分的被测单元有3个,即炉11213},其中被测单元?1表示为< f Ktypel vl),f 1的输入输出信息〉,被测单元F2表示为< f2 (type2 v2),f2的输入输出信息 >,被测单元F3表示为< f3 (type3 v3),f3的输入输出信息〉。步骤112、人工干预划分时,由用户指定每个被测单元包括的若干个函数、类、文件,或者它们的任意组合,并循环执行,直到测试工程全部被划分完毕,得到测试工程的被测单元集合。步骤2、根据覆盖准则(包括语句、分支、C/DC、MC/DC、路径、函数、类、文件等),从抽象语法树和控制流图中提取被测单元中相应的待覆盖元素集合。其具体包括
步骤21、对于语句覆盖准则,提取被测试单元的函数中每一个可达语句块作为语句覆盖元素,组成语句覆盖元素集合。属于同一个块的语句若其中的某一语句被覆盖,则该块所有的语句均能被执行。步骤22、对于分支覆盖准则,提取被测试单元的函数中,每一个可达分支(与可被执行判定的结果一一对应)作为分支覆盖元素,组成分支覆盖元素集合。例如,对应在被测单元的控制流图上,所有有向边即为分支覆盖元素集合。步骤23、对于C/DC覆盖准则,提取被测试单元的函数中,每个覆盖元素包括
1)可被执行的判定表达式;
2)判定表达式中,所有取值既可以为真又可以为假的简单条件,由此遍历整个被测单元,组成C/DC覆盖元素集合。例如对应在被测单元的控制流图上,表示为
1)有向边E作为一个C/DC覆盖元素;
2)当E为判断节点N的一条分支时,<v>为一个C/DC覆盖元素,其中ν是N的判定表达式的一组谓词取值,它是由判定表达式满足C/DC覆盖准则的要求所确定的。步骤对、对于MC/DC覆盖准则,提取被测试单元的函数中,每个覆盖元素包括
1)可被执行的判定表达式;
2)判定表达式中,所有可以独立影响判定的简单条件,由此遍历整个被测单元,组成 MC/DC覆盖元素集合。例如对应在被测单元的控制流图上,表示为取控制流图上一条有向边E
1)当E为非判断节点的分支时,E作为一个MC/DC覆盖元素;
2)当E为判断节点N的一条分支时,<E,v>作为一个MC/DC覆盖元素,其中ν是N的判定表达式的一组谓词取值,它是由判定表达式满足MC/DC覆盖准则的要求所确定的。步骤25、对于路径覆盖准则,提取被测试单元的函数中,所有可达路径作为覆盖元素,组成路径覆盖元素集合。例如对应在被测单元的控制流图上,表示为提取控制流图上一个有序节点序列和一个有序有向边序列,使得该子图具有唯一输入节点和唯一输出节点,且输入节点为函数入口,输出节点为函数出口。步骤沈、对于函数覆盖准则,提取被测试单元的类(对于函数直接构成类的情况) 或者文件(对于函数直接构成文件的情况)中,所有可被执行函数作为函数覆盖元素,组成函数覆盖元素集合。假设函数中只要有一条路径可被执行,就认为该函数可被执行。步骤27、对于类覆盖准则,提取被测试单元的文件中所有可被执行的类作为元素, 构成类覆盖元素集合。假设类中只要有一个函数被执行,就认为该类被执行。步骤观、对于文件覆盖准则,提取被测试单元中所有可被执行文件作为元素,组成文件覆盖元素集合。对于由类直接组成文件的情况,假设文件中只要有一个类可被执行,就认为该文件可被执行。对于由函数直接组成文件的情况,假设文件中只要有一个函数可被执行,就认为该文件可被执行。步骤3、根据上述覆盖准则,在被测单元的程序中插入相应的探针函数。下面以典型程序statistics, c具体说明如何根据不同覆盖准则插入探针函数。 程序功能为输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。源程序如下
#include 〃stdio. h〃
void statistics(char c)
{
int Ietters=Ojspace=0,digit=0,others=0;
if (c!=,V)
{
if (c>=,a,&&c〈=,z,I I c>=,A,&&c〈=,Z,)
letters++; else if (c==,,)
space++; else if(c>=,0,&&c〈=,9,) digit++; else
others++;
ι
printf("all in all :char = %d space = %d digit = %d others=%d\
η〃,letters, space, digit, others); }·
该步骤3具体包括
步骤31、对于语句覆盖准则,在语句覆盖元素集合的每个元素(均为可达语句块)中插入语句探针函数。语句采用以“块”为单位的语句插装,这里,所谓块就是逻辑上连续执行的相邻最大的语句集。现在在以下结点处插入语句探针函数函数的开始处、if语句块、else语句块、case语句块、default语句块、label语句块、for语句块、while语句块、do-while语句块、catch语句块、finally语句块、跳转语句前。语句探针函数void _Block_Cov(int blockNum)表示在插装点对应的语句块的所有语句得到执行。其中blockNum唯一标识一个语句块的抽象语法树根结点,当语句块被执行时,语句块对应的标识符被记录。语句探针函数实现如下
void_Block_Cov(int blockNum)
{
cppTestSendData(blockNum);
ι
源代码为a=d+b ;
10插装后的代码为 a=d+b;
—Block—Cov(Num);
由上述分析可得到被测程序statistics, c在语句覆盖准则下的探针函数插入结果 #include 〃stdio· h〃
void statistics(char c)
{
int Ietters=O, space=0, digit=0, Others=O; _Block_Cov(0);
if (c!=,\n')
{
_Block_Cov(l);{
if (c>=' a,&&c<=' z' I I c>=,A,&&c<=' Z')
{
_Block_Cov(2);letters++;
}
else {
_Block_Cov(3) ; if (c==',)
{
—Block—Cov(4);space++;
ι
else {
_Block_Cov (5) ; if (c>=' O,&&c<=' 9,)
{
—Block—Cov(6);digit++;
ι
else {
—Block—Cov(7);others++;
ι ι ι ι ι
printf("all in all :char = %d space = %d digit = %d others=%d\ η〃,letters, space, digit, others);
ι
记为instrumentjtatistics. c,其中探针函数的正负返回取值的上下限可人为设置。步骤32、对于分支覆盖准则,在分支覆盖元素集合每个元素中插入分支探针函数。分支探针函数 bool _Bran_Cov(bool exp, Int PositiveBranchId, intnegitiveBranchld)获取运行时分支情况,并且不改变源代码的执行逻辑。在运行时根据接收到的数字是正数还是负数,来判别相应分支的取值。其中返回值PositiveBranchld和 negitiveBranchld分别表示分支取值为真和假。分支探针函数的实现如下
bool _Bran_Cov(bool exp, Int PositiveBranchld, int negitiveBranchld)
{
if (exp)
cppTestSendData (PositiveBranchld);
else
cppTestSendData (negitiveBranchld); return exp;//不改变程序的执行逻辑
}
源代码if(a&&b)
插装后代码if (_Branch_Cov (a&&b, trueNum, FalseNum))
由上述分析可得到被测程序statistics, c在分支覆盖准则下的探针函数插入结果
void statistics(char c)
{
int Ietters=Ojspace=0,digit=0,others=0; —Block—Cov(O);
if (—Bran—Co ν (c!=,\n,,-2147483647,1))
{
if(—Bran—Cov(c>=’a’&&c〈=’z’ | | c>=’ A’ &&c〈=’ Z’,-2147483646,2)) letters++;
else if (_Bran_Cov(c== \-2147483645,3)) space++;
else if (—Bran—Cov (c>=,O,&&c〈=,9,,-2147483644,4)) digit++;
else
others++;
ι
printf(〃all in all:char=%d space=%d digit=%d others=%d\n〃,letters, space, digit, others);
ι
记为instrumentjtatistics. c,其中探针函数的正负返回取值的上下限可人为设置。步骤33、对于C/DC覆盖准则,在C/DC覆盖元素集合的每个元素中插入探针函数, 即在每个可被执行判定中插入分支探针函数,在对应判定中所有取值既可以为真又可以为假的简单条件处插入条件探针函数。# ^ # 0 ^ bool _Cond_Cov(bool exp, int positiveCondld, int negitiveCondld)获取运行阶段被执行简单条件的取值情况,并且不改变源代码的执行逻
12辑。在运行时根据接收到的数字是正数还是负数,来判别相应判定的取值。其中返回值 positiveCondld和negitiveCondld分别表示条件取值为真和假。条件探针的实现如下
bool _Cond_Cov(bool exp, Int positiveCondld, int negitiveCondld)
{
if (exp)
cppTestSendData (positiveCondld);
else
cppTestSendData (negitiveCondld); return exp;//不改变程序的执行逻辑
}
在判定表达式上插入分支探针并为判定表达式内的每个条件表达式插入条件探针。在动态运行时,根据接收到的插装信息,得到分支取值真假和分支内条件的取值真假。源代码if(a&&b),
插入分支探针和条件探针后的代码
if (_Branch_C0V(if(_Cond_Cov(a, trueNum,falseNum)&&—Cond_Cov(b,trueNum, falseNum)),trueNum, FalseNum))
由上述分析可得到被测程序statistics, c在C/DC覆盖准则下的探针函数插入结果
void statistics(char c)
{
int Ietters=O, space=0, digit=0, others=0; _Block_Cov(0);
if(_Bran_Cov(_Cond_Cov(c!=,\n',-2147483647,1),-2147483646,2))
{
if(_Bran_Cov(_Cond_Cov(c> = ' a',-2 1 47483645, 3)&&_Cond_ Cov (c<=' z',-2147483644,4) | | _Cond_Cov (c>=,A,,-2147483643,5) &&_Cond_Cov (c<=' Z', -2147483642,6),-2147483641,7)) letters++;
else if(_Bran_Cov(_Cond_Cov(c==',,-2147483640,8),-2147483639,9)) space++;
else if(_Bran_Cov (_Cond_Cov(c>=' O,,-2147483638,10)&&_Cond_Cov(c<=' 9,,-2 147483637, 11),-2147483636, 12)) digit++;
else
others++;
}
printf("all in all :char = %d space = %d digit = %d others = %d\ η〃,letters, space, digit, others);
ι
13记为instrumentjtatistics. c,其中探针函数的正负返回取值的上下限可人为设置。步骤34、对于MC/DC覆盖准则,在MC/DC覆盖元素集合中的每个元素内插入探针函数。即在每个可被执行判定处插入分支探针函数,在对应判定中的所有可独立影响判定的简单条件处插入条件探针函数,方法同步骤32和步骤33。步骤35、对于路径覆盖准则,基于语句覆盖进行统计,所以不用额外插入探针函数。步骤36、对于函数覆盖准则,基于路径覆盖进行统计,所以不用额外插入探针函数。步骤37、对于类覆盖准则,基于函数覆盖进行统计,所以不用额外插入探针函数。步骤38、对于文件覆盖准侧,基于类或者函数覆盖进行统计,所以不用额外插入探针函数。步骤4、根据用户测试需求,选择采用系统自动执行方式或用户手动执行方式对插入探针函数的被测单元进行动态测试。 其中,所述步骤4具体包括
步骤41、对于系统自动执行,系统自动生成被测单元的测试用例,并将其生成可执行文件,进行测试执行。自动测试执行的过程如图3所示,对于一个测试单元,生成对应的测试用例库,用来保存所有有效的测试用例。该步骤41进一步包括
步骤411、系统根据覆盖准则以及被测单元的输入参数生成相应的测试用例; 步骤412、生成驱动文件,用于逐个调用测试用例;
步骤413、将驱动文件和步骤3中插入探针函数之后的被测单元所在文件链接生成可执行文件;
步骤414、运行可执行文件,同时测试结果将被记录和分析,并最终生成一个结果分析报告,将所有有效的测试用例生成测试用例库。例如对于被测程序statistics, c,系统根据其输入参数类型和范围生成一个测试用例(‘b,),并生成驱动文件 driverFile_statistics. c,将 driverFile_statistics. c 与插入探针函数之后的被测单元文件instrumentstatistics. c进行链接,生成可执行文件 test_statistics. exe,然后运行可执行文件,并得到测试用例库testcase_statistics. mdb0步骤步骤42、对于用户手动执行,由用户手动对预处理后的待测程序生成可能的桩函数、测试用例和驱动文件,并将驱动文件和步骤3中插入探针函数之后的被测单元所在文件进行链接,生成可执行文件并运行,进行测试执行。以源程序statistics, c为例,预处理后用户根据函数信息,生成桩函数_STUB_ statistics,进而生成桩代码,然后根据指定的测试用例(例如‘b’),生成驱动函数_ DRIVEILstatistics,调用测试用例,最后将桩代码、驱动函数、插入探针函数之后的被测程序进行链接,生成可执行文件testjtatistics. exe,运行可执行文件,进行测试执行。步骤5、根据动态测试执行的返回信息,得到测试单元的被覆盖元素集合,并计算被测单元的覆盖率。其具体包括
步骤51、利用被测试程序的探针函数的返回信息,得到被覆盖元素集合。其中步骤51进一步包括步骤511、对于语句覆盖准则,探针函数返回测试过程中被测单元语句覆盖集合的所有被覆盖语句块对应的数字。例如在步骤4中执行的测试用例(‘b’),被测单元statistics, c的探针函数返回结果为0,1,2,由此可知探针函数 _Block_Cov (0),_Block_Cov (1),_Block_Cov (2)所标识的语句块被覆盖。步骤512、对于分支覆盖准则,探针函数返回测试过程中被测单元分支覆盖集合的所有被覆盖的分支对应的数字。例如在步骤4中执行的测试用例(‘b’),被测单元statistics, c的探针函数返回结果为0,-2147483647,-2147483646,由此可知探针函数 _Bran_Cov (0),_Bran_Cov (-2147483647), _Bran_Co ν (-2147483646)所标识的分支被覆盖。步骤513、对于C/DC覆盖准则,探针函数返回测试过程中被测单元C/DC覆盖集合的被覆盖元素(所有被覆盖的判定,以及判定中被覆盖的所有简单条件)对应的数字。步骤514、对于MC/DC覆盖准则,探针函数返回测试过程中被测单元MC/DC覆盖集合的被覆盖元素(所有被覆盖的判定,以及判定中所有被覆盖的可独立影响判定的简单条件)对应的数字。步骤515、对于路径覆盖准则,根据步骤Ell中获得的语句覆盖集合的被覆盖语句块,按照一条路径被覆盖当且仅当此路径上的所有语句块被覆盖的原则,提取出被测试单元的所有被覆盖路径。步骤516、对于函数覆盖准则,根据步骤E15中获得的路径覆盖集合中被覆盖路径,按照一个函数被覆盖当且仅当此函数中至少有一条路径被覆盖的原则,提取出被测试类的所有被覆盖函数(对于文件直接由类构成的情况)或文件中的所有被覆盖函数(对于文件直接由函数构成的情况)。步骤517、对于类覆盖准则,根据步骤E16中获得的被覆盖函数,按照一个类被覆盖当且仅当此类中至少有一个函数被覆盖的原则,提取出被测试文件的所有被覆盖类。步骤518、对于文件覆盖准则,根据步骤E17中获得的被覆盖类(对于文件直接由类构成的情况),按照一个文件被覆盖当且仅当此文件中至少有一个类被覆盖的原则,或者根据E16中获得的被覆盖函数(对于文件直接由函数构成的情况),按照一个文件被覆盖当且仅当此文件中至少有一个函数被覆盖的原则,提取出被测试工程的所有被覆盖文件。步骤52、分析覆盖结果,通过图形界面的方式标识出源代码中已覆盖元素和未覆盖元素,并计算出被测单元的语句覆盖率、分支覆盖率、C/DC覆盖率、MC/DC覆盖率、路径覆盖率、函数覆盖率、类覆盖率、文件覆盖率。其中步骤52进一步包括
步骤521、统计语句覆盖的覆盖率,首先统计步骤511中得到的语句覆盖元素集合被覆
盖的语句块元素个数。通过图形界面的方式标识出源代码中已被覆盖的语句块元素和未被
覆盖的语句块元素。然后统计步骤21中提取出的语句覆盖元素集合的元素总个数,用被覆
盖的语句块元素个数除以语句覆盖元素集合的元素总个数,即可计算出语句覆盖率。
_ , CoveredBIockEkmeniMim CoveredRate _ Block =-* 1 U0%
ToialBlock EhmmtiNum上述公式中变量含义如下CoveredP^iie _Block .语句覆盖率
CoveredBlo ckEhmsniNum 语句覆盖元素集合中被覆盖的元素个数 TotalBhck EkmentNum 语句覆盖元素集合的元素总个数
步骤522、统计分支覆盖的覆盖率,首先统计步骤512中得到的分支覆盖元素集合被覆
盖的分支元素个数。通过图形界面的方式标识出源代码中已被覆盖的分支元素和未被覆盖
的分支元素。然后统计步骤22中提取出的分支覆盖元素集合的元素总个数,用已被覆盖的
分支元素个数除以分支覆盖元素集合的总元素个数,即可计算出分支覆盖率。
权利要求
1.一种基于覆盖率量化指标确定软件测试过程充分性的方法,其特征在于,该方法主要包括A、对被测程序进行预编译、词法分析和语法分析,得到程序的抽象语法树、控制流图和函数之间的调用关系图,并根据用户测试需求,自动生成被测单元;B、根据覆盖准则,从所述抽象语法树和控制流图中提取被测单元中相应的待覆盖元素集合;C、根据所述的覆盖准则,在被测单元的程序中插入相应的探针函数;D、根据用户测试需求,选择系统自动执行或用户手动执行的方式对插入探针函数的被测单元进行动态测试;E、根据动态测试执行的返回信息,得到测试单元的被覆盖元素集合,并计算被测单元的覆盖率。
2.根据权利要求1所述的基于覆盖率量化指标确定软件测试过程充分性的方法,其特征在于,所述步骤A包括根据被测程序中的函数调用关系,对被测程序进行单元划分,得到被测单元;所述被测单元为根据用户测试需求,将被测试程序划分成的独立的测试对象,其为一个或多个函数、 类、文件。
3.根据权利要求1所述的基于覆盖率量化指标确定软件测试过程充分性的方法,其特征在于,所述步骤B包括对于语句覆盖准则,提取被测试单元的函数中每一个可达语句块作为语句覆盖元素, 组成语句覆盖元素集合;对于分支覆盖准则,提取被测试单元的函数中,每一个可达分支作为分支覆盖元素,组成分支覆盖元素集合;对于C/DC覆盖准则,提取被测试单元的函数中,每个覆盖元素包括可被执行的判定表达式;判定表达式中,所有取值既可以为真又可以为假的简单条件,由此遍历整个被测单元,组成C/DC覆盖元素集合;对于MC/DC覆盖准则,提取被测试单元的函数中,每个覆盖元素包括可被执行的判定表达式;判定表达式中,所有可以独立影响判定表达式结果的简单条件,由此遍历整个被测单元,组成MC/DC覆盖元素集合;对于路径覆盖准则,提取被测试单元的函数中,所有可达路径作为覆盖元素,组成路径覆盖元素集合;对于函数覆盖准则,提取被测试单元的类(对于函数直接构成类的情况)或者文件(对于函数直接构成文件的情况)中,所有可被执行的函数作为函数覆盖元素,组成函数覆盖元素集合;假设函数中只要有一条路径可被执行,就认为该函数可被执行;对于类覆盖准则,提取被测试单元的文件中所有可被执行的类作为类覆盖元素,构成类覆盖元素集合;对于文件覆盖准则,提取被测试单元中所有可被执行的文件作为文件覆盖元素,组成文件覆盖元素集合;对于由类直接组成文件的情况,该文件中只要有一个类可被执行,就认为该文件可被执行;对于由函数直接组成文件的情况,该文件中只要有一个函数可被执行, 就认为该文件可被执行。
4.根据权利要求1所述的基于覆盖率量化指标确定软件测试过程充分性的方法,其特征在于,所述步骤C包括对于语句覆盖准则,在语句覆盖元素集合的每个元素中插入探针函数,以便记录执行测试用例过程中语句块的被覆盖情况;对于分支覆盖准则,在分支覆盖元素集合每个元素中插入分支探针函数,以便记录执行测试用例过程中分支的被覆盖情况;对于C/DC覆盖准则,在C/DC覆盖元素集合的每个元素中插入探针函数,即在每个可执行判定中插入分支探针函数,在对应判定中所有取值既可以为真又可以为假的简单条件处插入条件探针函数,以便记录执行测试用例过程中C/DC元素的被覆盖情况;对于MC/DC覆盖准则,在MC/DC覆盖元素集合中的每个元素内插入探针函数;即在每个可执行判定处插入分支探针函数,在对应判定中的所有可独立影响判定的简单条件处插入条件探针函数,以便记录执行测试用例过程中MC/DC元素的被覆盖情况;对于路径覆盖准则,基于语句覆盖进行统计,所以不用额外插入探针函数; 对于函数覆盖准则,基于路径覆盖进行统计,所以不用额外插入探针函数; 对于类覆盖准则,基于函数覆盖进行统计,所以不用额外插入探针函数; 对于文件覆盖准侧,基于类或者函数覆盖进行统计,所以不用额外插入探针函数。
5.根据权利要求1或4所述的基于覆盖率量化指标确定软件测试过程充分性的方法, 其特征在于,所述步骤D包括对于系统自动执行,系统自动生成被测单元的测试用例,生成驱动文件,逐个调用测试用例,将驱动文件和插入探针函数之后的被测单元所在文件链接生成可执行文件,然后运行可执行文件,进行测试执行;对于用户手动执行,由用户手动对预处理后的待测程序生成可能的桩函数、测试用例和驱动文件,并将驱动文件和所述的插入探针函数之后的被测单元所在文件进行链接,生成可执行文件并运行,进行测试执行。
6.根据权利要求1所述的基于覆盖率量化指标确定软件测试过程充分性的方法,其特征在于,所述步骤E具体包括E1、利用被测试程序的探针函数的返回信息,得到被覆盖元素集合; E2、分析覆盖结果,通过图形界面的方式标识出源代码中已覆盖元素和未覆盖元素,并计算出被测单元的语句覆盖率、分支覆盖率、C/DC覆盖率、MC/DC覆盖率、路径覆盖率、函数覆盖率、类覆盖率、文件覆盖率。
7.根据权利要求1所述的基于覆盖率量化指标确定软件测试过程充分性的方法,其特征在于,所述步骤El包括E11、对于语句覆盖准则,探针函数返回测试过程中被测单元语句覆盖集合的所有被覆盖语句块对应的数字;E12、对于分支覆盖准则,探针函数返回测试过程中被测单元分支覆盖集合的所有被覆盖的分支对应的数字;E13、对于C/DC覆盖准则,探针函数返回测试过程中被测单元C/DC覆盖集合的被覆盖元素(所有被覆盖的判定以及判定中所有被覆盖的简单条件)对应的数字;E14、对于MC/DC覆盖准则,探针函数返回测试过程中被测单元MC/DC覆盖集合的被覆盖元素(所有被覆盖的判定,以及判定中所有被覆盖的可独立影响判定的简单条件)对应的数字;E15、对于路径覆盖准则,根据步骤Ell中获得的语句覆盖集合的被覆盖语句块,按照一条路径被覆盖当且仅当此路径上的所有语句块被覆盖的原则,提取出被测试单元的所有被覆盖路径;E16、对于函数覆盖准则,根据步骤E15中获得的路径覆盖集合中被覆盖路径,按照一个函数被覆盖当且仅当此函数中至少有一条路径被覆盖的原则,提取出被测试类的所有被覆盖函数(对于文件直接由类构成的情况)或文件中的所有被覆盖函数(对于文件直接由函数构成的情况);E17、对于类覆盖准则,根据步骤E16中获得的被覆盖函数,按照一个类被覆盖当且仅当此类中至少有一个函数被覆盖的原则,提取出被测试文件的所有被覆盖类;E18、对于文件覆盖准则,如果文件直接由类构成,根据步骤E17中获得的被覆盖类,按照一个文件被覆盖当且仅当此文件中至少有一个类被覆盖的原则,或者根据E16中获得的被覆盖函数,按照一个文件被覆盖当且仅当此文件中至少有一个函数被覆盖的原则,提取出被测试工程的所有被覆盖文件。
全文摘要
本发明提供一种基于覆盖率量化指标确定软件测试过程充分性的方法,包括A、对被测程序进行预编译、词法分析和语法分析,得到程序的抽象语法树、控制流图和函数之间的调用关系图,并根据用户测试需求,自动生成被测单元;B、根据覆盖准则,从所述抽象语法树和控制流图中提取被测单元中相应的待覆盖元素集合;C、根据所述的覆盖准则,在被测单元的程序中插入相应的探针函数;D、根据用户测试需求,选择系统自动执行或用户手动执行的方式对插入探针函数的被测单元进行动态测试;E、根据动态测试执行的返回信息,得到测试单元的被覆盖元素集合,并计算被测单元的覆盖率。应用该方法,能够提高软件评估测试的效率和准确性。
文档编号G06F11/36GK102419728SQ20111033891
公开日2012年4月18日 申请日期2011年11月1日 优先权日2011年11月1日
发明者周傲, 宫云战, 王思岚, 王雅文, 谭立力, 赖思佳, 韩春晓 申请人:北京邮电大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1