一种单元测试系统和方法

文档序号:6573977阅读:171来源:国知局
专利名称:一种单元测试系统和方法
技术领域
本发明涉及软件测试技术,更具体地说是一种在单元测试中实现通用 驱动函数的方法。
背景技术
单元测试中驱动函数的编写工作量是比较大的,每个被测函数至少对 应一个驱动函数,而且需要经常性的修改编译,影响单元测试效率。目前 解决这一问题基本上基于两个思路1、手工用脚本来写。优点是不用重复 编译,适用于被测代码变化少,而驱动函数变动多的场景。缺点是编写工 作量没有减少,而且使用者需要学习一种新的脚本语言,学习曲线长。2、 自动生成驱动函数,优点是减少了驱动函数编写的工作量,缺点是增加了 测试工具的复杂性,如果需要在各种编译环境下都能自动生成驱动函数, 很容易产生编译错误,对测试工具的要求极高。发明内容有鉴于此,本发明要解决的技术问题是提供一种单元测试系统和方法, 可以减少单元测试过程中驱动函数编写工作量,并且这种方法的实现难度 较小,能够在各种操作系统、编译环境下实现。为实现本发明要解决的技术问题,本发明的单元测试系统,包括被 测单元、缓冲单元、通用驱动单元、测试控制单元、信息提取单元;所述 信息提取单元以被测单元为输入,用于提取被测单元的信息;所述测试控 制单元用于调用信息提取单元获得的被测单元的信息,并在测试前把调用 的信息放入缓冲单元,并控制所述通用驱动单元进行测试;通用驱动单元 从缓冲单元获取信息,并放入设定的测试环境,调用被测函数,并将输出 值放入缓冲单元;所述测试控制单元还用于从缓冲单元中提取输出值完成 测试结果的判断。优选的,所述信息提取单元从被测单元中提取的信息包括被测单元 的数据结构、函数参数、返回值、全局变量。
优选的,还包括符号表单元,用于封装信息提取单元提取的信息,并 提供对外接口。优选的,所述信息提取单元具体通过静态扫描分析方式提取被测单元 的信息。本发明提出的单元测试方法,包括以下处理步骤1) 信息提取单元从被测单元中提取信息;2) 测试控制单元用于调用信息提取单元获得信息并存入缓冲单元;3) 通用驱动单元从缓冲单元获取信息,并放入设定的测试环境,调用 被测函数,执行测试过程,并将输出值存入缓冲单元;4) 测试控制单元还用于从缓冲单元中提取输出值完成测试结果的判断。优选的,所述步骤1)中提取的信息包括被测单元的数据结构、函 数参数、返回值、全局变量。优选的,所述步骤1)之后还包括信息提取单元将提取的信息存入符 号表单元的处理步骤。优选的,所述步骤1)中信息提取单元采用静态扫描分析方式提取被 测单元的信息。采用本发明提出的单元测试系统和方法能够有效提高单元测试的效 率和质量,减少人力成本,并且测试用例能够不断修改复用,大大减少重 复劳动。具体包括以下优点1、 通过对被测模块提取结构信息,使用户不需要关心程序的结构;2、 驱动函数只有一个,不需要编写大量驱动函数和测试脚本,降低了 对测试人员的技能要求;3、 职责清晰,用户只需要提供函数所需要的输入输出数据,其他都由 通用驱动函数处理,有利于实现数据驱动的单元测试,可复用性和灵活 性大大提高。4、 如果通过可视化界面编辑输入输出数据,易用性将会大大提高。5、 被测程序一次编译后,可灵活创建并运行多个测试用例,减少了系
统的编译次数;6、 被测程序可以在目标机上,也可以在PC机上,能够灵活适应多种 测试环境。


图1是本发明优选实施例单元测试系统结构示意图;图2是本发明优选实施例单元测试方法被测函数调用流程图。
具体实施方式
本发明的核心思想是用一个通用的驱动函数代替大量的驱动函数, 用类似编译器的方法直接访问程序堆栈,从而能够把各种声明不同的驱动 函数统一到同 一个驱动函数中来。为使本发明的目的、技术和优点更加清楚,下面结合附图对本发明做 进一步的详细描述。图1示出了依据本发明的单元测试系统模块结构示意图,说明了本发 明中的主要模块结构。本发明包括通用驱动单元101,缓冲单元102,信 息提取单元103、符号表单元104,被测单元105,测试控制单元106。其中,通用驱动单元101是本发明的主要部分,它主要与缓冲单元102 进行交互。它从缓冲单元102获得被测函数的输入值(包括参数、全局变 量的值),通过一定的方法把值放入当前执行环境,调用被测函数,并把被 测函数的输出值(包括;返回值、出参、全局变量的值)放入缓冲单元102。缓冲单元102模块提供了一个用于存储函数参数、全局变量、返回值 的信息、执行前、执行后结果的缓冲区,以及访问该缓冲区的API,该模 块解决了数据的存储问题。缓冲区结构中主要包括了如下字段Index—参 数的索引,VarName—全局变量的名称,size—所占字节大小,pointerflag 一是否为指针(数组和指针同样处理),,data—用来存放数值的数据块。测 试控制单元106需要在测试前把被测函数的参数、全局变量的值放入缓冲 区;在执行通用驱动单元101后,测试控制单元106需要从缓冲单元102 获取被测函数的返回值、出参、全局变量的值,判断结果是否正确。信息提取模块103以被测单元105为输入,通过对被测单元105进行 分析(如对被测模块源文件进行静态扫描分析,但本发明也可以适用于其 他形式的分析过程),获取被测单元(105)的数据结构、函数参数、返回
值、全局变量的信息,并通过符号表单元104存取这些信息,这些信息是 通用驱动单元101运行的基础。符号表单元104封装了信息提取单元103获取的信息,并提供了对外 接口,以供其他模块获取被测函数的参数、返回值、全局变量的类型、大 小等信息。被测单元105代表被测试的函数,在编译之前是包含了一组被测函数 的源文件,在编译之后是一组由被测函数源文件生成的二进制代码。测试控制单元106是实现测试控制的模块,它调用信息提取单元103 获取被测单元105的数据结构、函数参数、返回值、全局变量的信息,在 测试前把被测函数的输入值(参数、全局变量的值)放入缓冲单元102,并 在调用通用驱动单元101后从缓冲单元105获取被测函数的返回值、出参、 全局变量的值,判断结果是否正确。因为有了缓冲单元的设计,测试控制 单元很容易做到数据驱动的自动化测试。如图2所示出为通用驱动单元执行流程图,包括如下步骤 步骤201根据函数名获取函数地址,记为FuncAddr。根据不同的操作 系统,不同语言,不同编译器实现这一步骤有不同的方法。有些操作系统 如vxworks本身就提供这样的API,有些操作系统如windows不直接提供 API,但是可以通过分析编译器生成的.exe或者.map文件来获得函数地址。 因为本步骤不是本发明的重点内容,所以不再详细说明。步骤202査找缓冲单元,获取预置的被测函数参数、全局变量的值。 本发明中,缓冲单元提供了下列API以进行对缓冲区的设置和读取读取缓冲单元中的函数参数值; 设置缓冲单元中的函数参数值;读取缓冲区中的全局变量值; 设置缓冲区中的全局变量值;步骤203从缓冲单元获取被测函数的参数和全局变量信息,设置其全 局变量值,将入参按照一定规则压入程序当前堆栈。全局变量和函数一样作为全局符号,在编译时分配有地址,从缓冲区中 读取其预置值,设置该全局变量的值为预置值。设置被测函数的参数需要访问该被测函数的堆栈,以设置其执行时的参 数值。访问堆栈通过栈顶指针ESP访问,参数按照被测函数的调用约定顺 序入桟,并同时维护栈顶指针,保证堆栈的正确性。这一步的具体细节与
编译器紧密相关,随字节对齐和函数调用约定不同而变化。下面以单字节对齐、—cdecl调用方式为例详细说明步骤203:1. 对于被测函数的n个参数,从第n个参数到第一个参数,依次做如 下操作(1) 获取该参数的缓冲区parabuffer,获取该参数所占字节数sizej(2) 如果该参数为指针,则将parabuffer的data数据块的地址入 栈。该参数的堆栈操作完成,回到l,执行下一个参数的堆栈操作;(3) 如果参数大小不是4的整数倍,则补齐至4的整数倍size二 size+(4-size%4);(4) 执行指令sub esp,size,即将栈顶指针减小size;(5) 由于push指令只能对4字节内数据操作,考虑到大字节参数, 我们采用类似于memcpy的方式,将该参数的整个码流入栈,为了防止 memcpy函数调用对堆栈产生影响,直接使用汇编语言来替代memcpy函数 实现内存拷贝。(6) 累加被测函数所有参数所占的总字节数,记为AllSize;2. 对于被测函数中的每个全局变量,依次作如下操作(1) 获取该全局变量的缓冲区,记为pGlovar;(2) 获取该全局变量的地址,记为GlovarAdd;(3) 如果该全局变量为指针,则将地址拷贝至GlovarAdd中,否则 将全局变量的码流拷贝至GlovarAdd中.步骤204执行该被测函数,代码为—asm call FuncAddr。 步骤205获取全局变量、出参、函数返回值,存入缓冲区,并恢复函 数堆栈;下面说明步骤205的详细过程1. 对于被测函数的全局变量,依次做如下操作(1) 如果该全局变量为指针,此时该全局变量缓冲区的数据块内已经 存放了执行后的结果,无需其他操作,跳过该全局变量;(2) 如果该全局变量不是指针,需要获取全局变量的值,存放回缓冲 区中。2. 对于出参的值,显然,只有参数为指针的情况下,该参数才能作为 出参,而在此情况下,该参数的缓冲区的数据块中已经存放了该参
数的执行后的结果。3. 获取函数返回值的步骤如下(1) 获取被测函数返回值的缓冲区,记为reBuffer;(2) 获取寄存器eax的地址—asm mov retval,eax(3) 如果函数返回值为指针,则将eax内的值存入reBuffer的数据块;(4) 如果函数返回值所占字节数小于4个字节,这时寄存器eax内存 放了返回值的值,直接将该值取出存入缓冲即可;(5) 如果函数返回值所占字节数大于4个字节,这时寄存器eax内存 放的是函数返回值的地址,需要将该地址内的值取出,存入缓冲 区;4. 恢复函数地址使用步骤203中记录的被测函数所有参数所占的总字节数 AllSize来调整堆栈,伪码为—asmaddesp,AUSize。 在以上描述中以INTEL处理器,C语言举例说明,并不表示对本发明 应用范围的限制。通过以上模块结构图和通用驱动函数执行流程图的介绍,本发明的主要 思想已经阐述清楚。使用一个通用驱动函数来替代大量驱动函数是本发明 的实质内容,本发明在实现时可能有多种不同的方案,本文中所涉及的具 体实现方案只是其中一种。以上内容是结合具体的优选实施方式对本发明所作的进一步详细说 明,不能认定本发明的具体实施只局限于这些说明。对于本发明所属技术 领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若 干简单推演或替换,都应当视为属于本发明的保护范围。
权利要求
1.一种单元测试系统,其特征在于,所述系统包括被测单元(105)、缓冲单元(102)、通用驱动单元(101)、测试控制单元(106)、信息提取单元(103);所述信息提取单元(103)以被测单元(105)为输入,用于提取被测单元(105)的信息;所述测试控制单元(106)用于调用信息提取单元(103)获得的被测单元(105)的信息,并在测试前把调用的信息放入缓冲单元(102),并控制所述通用驱动单元(101)进行测试;通用驱动单元(101)从缓冲单元(102)获取信息,并放入设定的测试环境,调用被测函数,并将输出值放入缓冲单元(102);所述测试控制单元(106)还用于从缓冲单元(102)中提取输出值完成测试结果的判断。
2. 根据权利要求1所述的单元测试系统,其特征在于,所述信息提取 单元(103)从被测单元(105)中提取的信息包括被测单元(105)的数 据结构、函数参数、返回值、全局变量。
3. 根据权利要求1或2所述的单元测试系统,其特征在于,还包括符 号表单元(104),用于封装信息提取单元(103)提取的信息,并提供对外 接口。
4. 根据权利要求1或2所述的单元测试系统,其特征在于,所述信息 提取单元(103)具体通过静态扫描分析方式提取被测单元(105)的信息。
5. —种单元测试方法,其特征在于,所述方法包括以下处理步骤 O信息提取单元(103)从被测单元(105)中提取信息;2) 测试控制单元(106)用于调用信息提取单元(103)获得信息并存 入缓冲单元(102);3) 通用驱动单元(101)从缓冲单元(102)获取信息,并放入设定的 测试环境,调用被测函数,执行测试过程,并将输出值存入缓冲单元(102);4) 测试控制单元(106)还用于从缓冲单元(102)中提取输出值完成 测试结果的判断。
6. 根据权利要求5所述的单元测试方法,其特征在于,所述步骤l) 中提取的信息包括被测单元(105)的数据结构、函数参数、返回值、全 局变量。
7. 根据权利要求5或6所述的单元测试方法,其特征在于,所述步骤1)之后还包括信息提取单元(103)将提取的信息存入符号表单元(104) 的处理步骤。
8.根据权利要求5或6所述的单元测试方法,其特征在于,所述步骤 1)中信息提取单元(103)采用静态扫描分析方式提取被测单元(105)的 信息。
全文摘要
本发明公开了一种单元测试系统和方法,系统包括被测单元(105)、缓冲单元(102)、通用驱动单元(101)、测试控制单元(106)、信息提取单元(103)。采用本发明提出的单元测试系统和方法能够有效提高单元测试的效率和质量,减少人力成本,并且测试用例能够不断修改复用,大大减少重复劳动。
文档编号G06F11/36GK101110024SQ20071007574
公开日2008年1月23日 申请日期2007年8月14日 优先权日2007年8月14日
发明者亮 马, 军 马 申请人:中兴通讯股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1