一种单元测试自动化方法 技术领域 本发明涉及单元测试领域,特别是一种单元测试自动化方法。
背景技术 单元测试是集中对由源代码实现的每一个程序单元进行测试,检查各个程序模块是否正确地实现了规定的功能。单元测试检查每一个控制结构的分支以确保完全覆盖和最大可能的错误检查。
目前,一般通过在程序代码中增加测试代码、编写大量的桩函数和驱动函数的方法来完成单元测试。这种方法最大的问题就是需要修改大量的程序代码,而且测试过程不能自动化,测试的执行效率非常低。
单元测试是为了尽可能多的发现程序的错误,发现错误后,为了修正错误,是需要对程序代码进行修改的。每当程序代码被修改的时候,程序配置的某些方面(如文档或者数据)也会被修改。回归测试是对修改过的程序再重新测试一遍,以保证修改是正确的,同时保证所做的修改不会带来不可预料的行为或者新的错误。
由于测试过程不能自动进行,因此对于错误修改后的回归测试过程就会十分繁琐。必需将测试正确的测试用例再重新测试一遍,以确保修改是正确的,并且没有引入其他的错误。
对于一些难以模拟的情况,如内存分配失败时,因为根本无法执行到这些代码,所以其对应的代码处理分支在单元测试时就难以覆盖了。
测试完成,发布版本的时候,还需要从程序代码中删除大量的测试代码,这个过程往往复杂而且极易出错。
综上所述,测试过程的自动化将成为单元测试发展的方向。
发明内容 有鉴于此,本发明的目的在于提供一种单元测试自动化方法,实现单元测试过程的自动化,提高单元测试的效率。
为了达到上述目的,本发明提供了一种单元测试自动化方法,其特征在于:设置用于测试程序单元的测试脚本文件、用于对测试脚本文件进行解释和执行的脚本解释器、以驱动函数和桩函数封装的单元测试辅助模块,该方法包含以下步骤:
A、脚本解释器解释执行测试脚本文件中的程序代码,根据程序代码的执行结果向数据交换文件中写入设置数据;
B、被测试程序单元调用单元测试辅助模块中的功能函数,单元测试辅助模块中的功能函数读取数据交换文件中的设置数据,通过设置数据控制重新定义的关键字(如:if语句)和函数的执行结果。
较佳地,该方法进一步包括:测试脚本文件通过延时控制设置数据交换文件中数据生效的时间。
测试脚本文件可引用动态连接库中的函数。测试脚本文件与被测试程序单元进行信息交互,根据测试脚本文件调用的动态连接库函数,选择测试脚本文件当前程序代码后面的程序代码分支。
本发明通过将测试用桩函数和驱动函数封装成一个通用独立的单元测试辅助模块,并通过测试脚本文件控制桩函数和驱动函数,从而控制被测试程序单元。更进一步地,对于一些难以模拟的分支的覆盖(如:内存分配失败),可以通过控制被测试程序单元进入不同的运行流程来实现。提高了单元测试的执行效率,实现了单元测试过程的自动化,使单元测试简单通用;回归测试时,只需使用该测试脚本文件重新进行测试即可,大大简化了回归测试,降低了单元测试的成本。针对同一单元测试的测试脚本文件可以重复使用,不管是否由同一测试人员进行测试。
图1示出了依据本发明的测试脚本文件控制被测试程序单元的示意图。
为了使本发明的目的、技术方案和优点更加清楚,下面结合附图对本发明作进一步地详细描述。
图1示出了依据本发明的测试脚本文件控制被测试程序单元的示意图,如图1所示:
进行单元测试时,测试系统主要分为如下几个部分:测试脚本文件101、脚本解释器102、数据交换文件103、单元测试辅助模块105和被测试程序单元104。其中单元测试辅助模块105和被测试程序单元104组成了被测试系统106。本发明是将测试的驱动函数和桩函数封装成一个通用独立的单元模块,即单元测试辅助模块105。
测试脚本文件101是一个文本文件,文件中包含了一些采用C语言编写的程序代码。用户根据测试所要实现的目的编写测试脚本文件101中的程序代码。测试脚本文件101还可以引入其他动态连接库中的函数,因此测试脚本文件101可实现灵活的功能,并且具有很强的可扩展性。例如,测试脚本文件101可通过延时来控制各类设置数据生效的时间间隔。又如,测试脚本文件101还可以通过调用外部动态连接库中的函数来和被测试程序单元104进行信息交换,从而根据不同的情况来决定测试脚本文件101中当前程序代码后面的程序代码的行为,比如执行测试脚本文件101中的哪一个分支。
脚本解释器102负责对测试脚本文件101进行解释和执行工作。脚本解释器102在读取测试脚本文件101后,逐条语句执行。在执行过程中,脚本解释器102依据执行结果,向数据交换文件103中写入一些设置数据,如设置某条if语句执行结果为false,设置某行new操作返回值为空等。
被测试程序单元104调用单元测试辅助模块105中的功能函数,单元测试辅助模块105中的功能函数读取数据交换文件103中的设置数据,通过设置数据控制重新定义的关键字和函数的执行结果,从而由单元测试辅助模块105控制被测试程序单元104。
单元测试辅助模块105控制被测试程序单元104的行为主要是通过重新定义各类主要关键字和函数来实现的。重新定义哪些关键字和哪些函数完全是根据测试需要来决定的,可以进行任意的扩展。
例如,测试过程中需要重新定义if语句,以达到控制if语句执行分支的目的,那么,可以对if语句(关键字)进行如下重新定义:
#define if(x)if(IfForUT(_FILE_,_LINE_,bool(x)))
其中,IfForUT是自定义的一个函数,其函数形式如下:
bool IfForUT(LPCSTR lpszFileName,int nLine,bool bCondition);
IfForUT函数中就可以从数据交换文件中读取设置数据,如果用户设置lpszFileName所指的文件中的nLine行语句要返回false,则IfForUT直接返回false。如果没有设置,IfForUT函数返回bCondition的值,也就是使if语句按其原有的行为执行。
再如,测试过程中希望模拟new操作失败,但又不希望修改被测试程序单元,那么,可以将new操作符进行重新定义:
#define new DEBUG_NEW
#define DEBUG_NEW new(THIS_FILE,_LINE_)
void*operator new(size_t nSize,LPCSTR lpszFileName,int nLine)
在自定义的new操作中就可以从数据交换文件中读取设置数据,根据用户在脚本文件中的设置来判断lpszFileName所指的文件中的nLine行的内存申请操作是否返回失败。这样就达到了模拟实际情况下几乎不可能模拟的内存分配失败的情况,而内存分配失败后的代码处理分支也就可以顺利地进行测试了。
再举例说明重新定义函数的情况。
在测试过程中希望对DBLibrary提供的函数dbcmd的执行结果(返回值)进行控制,那么可定义如下宏:
#define dbcmd(dbproc,cmdstring)dbcmdForUT(_FILE_,_LINE_,dbproc,cmdstring)
再定义函数dbcmdForUT
在dbcmdForUT函数中,类似前面举例说明的,可根据用户在脚本文件中的设置来确定lpszFileName所指文件中nLine行调用dbcmd函数时应该返回什么值。
这种方式对于单元测试中不同程序分支的测试可以实现完全自动化,可以使测试覆盖一些难以模拟的程序分支。而且用户可以在不同时间设置同一条语句返回不同的执行结果,这样就可以控制被测试程序单元104进入不同的运行流程。因此,可以在一次自动测试过程中,完成所有分支的测试。
测试所用的脚本文件101是可以重复使用的。在修改代码后,只需要将测试所用的脚本文件101重新执行一次,就可以完成回归测试,极大地提高了单元测试效率。
单元测试辅助模块105是否编译、加载完全通过宏定义来控制。因此,在单元测试结束后,只需要去掉宏,就可以完全卸载单元测试辅助模块105了,卸载后不会对发布版本的编译和执行产生任何影响。
总之,以上所述仅为本发明的较佳实施例而已,并非用于限定本发明的保护范围。