CN104731700A - 一种支持表格驱动局部数据的单元测试系统和方法 - Google Patents
一种支持表格驱动局部数据的单元测试系统和方法 Download PDFInfo
- Publication number
- CN104731700A CN104731700A CN201310714445.1A CN201310714445A CN104731700A CN 104731700 A CN104731700 A CN 104731700A CN 201310714445 A CN201310714445 A CN 201310714445A CN 104731700 A CN104731700 A CN 104731700A
- Authority
- CN
- China
- Prior art keywords
- variable
- local
- input
- code
- type
- 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.)
- Granted
Links
Abstract
本发明公开了一种支持表格驱动局部数据的单元测试系统和方法,所述局部数据包括局部输入和/或局部输出,其特征在于,包括:类型解析装置,用于解析数据类型定义获得类型信息;树表装置,由树形控件和表格控件组成;赋值比较装置,包括赋值装置和/或比较装置,用于给变量赋值和/或比较变量的实际值与预期值;局部数据设定装置,用于供用户指定局部输入变量及其输入位置和/或局部输出变量及其输出位置。本发明使实现了局部数据的表格驱动,不需要额外的测试驱动代码,不需要额外生成函数,支持复合类型,用户不需要编写、调试和维护额外的测试驱动代码和额外的函数,大幅提升了单元测试效率。
Description
技术领域
本发明涉及软件测试技术,特别是涉及软件单元测试技术。
背景技术
单元测试是软件开发过程中保证代码质量,提升开发产能的重要手段。
单元测试的基本方法是利用测试驱动代码,设定输入和预期输出,执行被测试程序,自动判断实际输出是否符合预期。输入数据和预期输出称为测试用例,也就是测试数据,这是单元测试工作的基本要素,而对输入的赋值过程和判断输出的比较过程,则是单元测试执行过程的核心。
局部数据是实施单元测试的难点问题。局部数据是指被测试代码执行过程中,某些变量在代码执行到某个位置时的数据。局部数据具有临时性,即代码执行到不同的位置,同一局部数据可能具有不同的值。
局部数据包括局部输入和/或局部输出。局部输入是指当被测试代码执行到某个位置时,测试用例对某个变量的赋值,被赋值的变量称为局部输入变量;局部输出是指当被测试代码执行到某个位置时,测试用例对某个变量的实际值与预期的输出值进行比较判断,被比较判断的变量称为局部输出变量。与测试用例的一般输入与输出一样,局部输入或局部输出也是测试用例的输入或输出。
被测试函数可能涉及的所有变量都有可能成为局部输入变量或局部输出变量,包括局部变量、参数、全局变量、成员变量,还可能包括这些变量的一个或多个成员,即设置局部输入或判断局部输出时,不一定针对整个变量,也可能只针对变量的一部分(一个或多个成员),表达式或表达式的一部分也可以作为局部输入变量或局部输出变量。一个变量是否需要作为局部输入变量或局部输出变量,是由测试的需求决定的,即如果测试用例需要对某个变量在被测试代码执行到某个位置时赋值,这个变量就是局部输入变量,如果测试用例需要对某个变量在被测试代码执行到某个位置时判断它的值,这个变量就是局部输出变量。局部输入或局部输出与一般输入或输出的根本区别在于,对于一般输入或输出,例如一个全局变量,输入是在被测试代码执行前进行赋值,属于前置条件,输出则用于在被测试代码执行完毕后对结果的比较判断,属于后置条件,而对于局部输入或局部输出,例如同一个全局变量,是在被测试代码执行过程中进行赋值或比较判断。同一个变量,例如一个全局变量,在同一个测试用例中,既可以作为一般的输入与输出,也可以同时作为局部输入或局部输出。
局部输入在单元测试中常见的需求场景有:
a.模拟中断对全局变量的修改。这在测试嵌入式项目时很常用,中断对单元测试的影响在于,被测试函数执行过程中,如果系统产生了中断,且中断调用了其他函数,而其他函数可能修改被测试函数中涉及的变量,那么,测试时需要模拟这种可能情形,以检测被测试代码在执行过程中遇到中断后的功能逻辑。被测试代码在执行过程中遇到中断的位置通常是不确定的,测试过程中需要由用户指定。中断调用的其他函数,能够修改的通常只有全局变量,因此,只要能在用户指定的被测试代码的某个位置设定某个全局变量的值,就可以满足单元测试过程中对中断测试需求,这种情形下,这个全局变量就是局部输入变量。
b.控制局部静态变量。局部静态变量通常需像全局变量一样,每个用例取值不同,但却无法像全局变量一样外部访问,因此也是一种局部输入变量。
c.简化数据的输入设置。有些数据的设置非常困难,例如,某些复杂的全局变量,要设置它的值可能很困难,而被测试代码只是涉及到该全局变量的一个小部分,这种情形下,如果将被测试代码涉及到的部分直接设置输入,而不是设置原来的全局变量,可以大幅减少工作量,例如下面的函数:
表达式*(ga.b.parr[index])指向复杂的全局变量中的一个成员,通过全局变量ga设置*(ga.b.parr[index])的值很困难,但*(ga.b.parr[index])实际上只是一个整数,如果将*(ga.b.parr[index])看作一个整数变量,对它的值直接设置,那么,既可以满足测试需求,测试数据也很简单。
d.对界面输入的模拟。理想状态下,代码的业务逻辑不应该与界面耦合,这对代码的可维护性、可重用性很有好处,但实际工作中,仍然有大量的业务逻辑与界面耦合,例如,业务逻辑涉及到的数据,需要从界面读入,由于单元测试一般不涉及界面,即测试执行过程中通常不会采用弹出输入界面的方式(否则无法实现自动执行的测试),这种输入在一般测试用例中是无法设置的,另外,从界面读入数据的代码通常会因为界面资源未建立而在执行测试过程中报错。这也是局部输入的一种应用场景。
e.模拟调用其他函数后的数据修改。调用其他函数后会被修改的数据,也可以作为一种局部输入变量,例如,一个变量,在调用其他函数时作为出参,调用后会获得新的值,那么,这个变量如果作为局部输入变量,在用例中设置它在调用其他函数后的值,也是很常见的测试需求。
以上是局部输入变量的需求场景举例。局部输出变量的常见的应用场景有:
a.判断某个变量在某个位置时的值是否符合预期。
b.对外部无法访问的变量,判断是否符合预期。
局部输出在单元测试中非常重要,很多时候,如果无法对局部数据判断输出是否符合预期,则测试无法进行,例如,通讯程序中计算了一个报文,报文由一个局部变量定义,计算完成后调用其他函数将报文发送出去,由于报文是一个局部变量,外部无法访问,通常情况下,无法判断计算结果是否正确,这样,计算过程将无法测试。再如,将计算结果调用其他函数存入数据库,计算结果没有通过返回值、出参等输出,那么,如果不能对计算结果是否符合预期进行判断,测试将无法进行。再如,一个全局变量参于被测试函数中多个逻辑块的计算,每个逻辑块的计算结果不同,需要判断在各个逻辑块中的计算结果。越是高层的代码,局部输出问题就越常见,不能解决局部输出变量的问题,是高层代码难以测试的主要原因之一。
综上所述,在单元测试中,局部数据包括局部输入和/或局部输出,这是单元测试的难点,解决局部数据的问题,对提升单元测试的适应性,提升测试效果,降低测试成本具有重要意义。特别是,如果局部输入和/或局部输出可以通过表格来驱动,即由表格来决定局部输入变量的输入值或局部输出变量的预期输出值,针对复合类型,由表格来决定哪些成员需要设置局部输入或局部输出以及局部输入或局部输出的值,将大幅提升单元测试工作的效率。
已经有个别单元测试工具实现了基本类型数据的表格化,也实现了对局部输入、局部输出的支持,基本类型的局部输入、局部输出可以移到表格中,例如广州凯乐软件技术有限公司于2013年3月份发布的单元测试工具Visual Unit3.0,具有局部数据模拟功能,其工作过程大致如下:
模拟局部输入:
a.用户指定局部输入的位置、局部输入变量类型、名称;
b.在测试驱动代码中插入局部输入代码,将用户设定的局部输入变量的值保存到内存,用户可以将局部输入代码中的基本类型的数据移到表格中;
c.生成一个局部输入函数,函数的返回类型为局部输入变量类型,该函数从内存读取步骤b所设置的局部输入变量的值并返回;
d.在被测试代码中插入代码,调用步骤c生成的函数,并用浅拷贝方式将局部输入函数的返回值赋给变量。
判断局部输出:
a.用户指定局部输出的位置、局部输出变量类型、名称;
b.在被测试代码中插入代码,用于将局部输出变量的值发送给测试工具;
c.用户在测试驱动代码中添加局部输出判断代码,判断代码调用工具提供的API函数,API函数将用户设定的预期输出值与步骤b中获得的值进行比较判断,这种比较只支持基本类型,用户可以将局部输出判断代码中的基本类型的数据移到表格中。
现有技术虽然实现了局部输入和局部输出的设置,但是,具有严重的缺陷:
a.每个局部输入变量需要使用一个额外的函数,虽然这种额外的函数由工具自动生成,但当用户对测试驱动代码或被测试代码或插入的局部输入代码修改时,均可能产生局部输入函数的类型不匹配、未定义、重定义等编译链接错误,由于局部输入函数是工具自动生成和维护的,发生问题时处理很麻烦;
b.需要额外的测试驱动代码,无论局部输入还是局部输出,均需要额外的测试驱动代码,尤其是对局部输出变量的判断,需要手工添加测试驱动代码;
c.需要手动将数据移到表格中;
d.不能将复合类型、数组、控指针等局部数据放在表格中,对于复合类型的局部输入或局部输出,需要先编写代码,将复合类型分解为基本类型,再将基本类型的数据移到表格中,这导致在面对复杂类型时,可能需要编写额外的大量测试驱动代码;
d.对局部输入变量的赋值过程,采用内存整体浅拷贝方式,当面对复杂的对象时,如复杂的C++对象,变量的赋值结果可能是不正确的,并且也无法满足只对复合变量的某些成员设置局部输入的需求;
e.由于是否设置局部输入或局部输出,除了插入代码来实现外,还需要由测试驱动代码来实现,因此,实质上是测试代码驱动,并不是真正的表格驱动。
综上所述,现有技术对于局部输入或局部输出的设置均需要额外的测试驱动代码,尤其是针对复合类型时,需要编写大量的额外测试驱动代码将复合类型分解为基本类型再将数据移到表格中,增加了调试和维护测试驱动代码的成本,需要手动将数据移到表格中,数据表格不支持复合数型、空指针、数组等局部输入或局部输出,并且对局部输入变量浅拷贝赋值可能导致赋值结果不正确,也不能满足只设置部分成员的需求,特别是,局部输入还需要额外的函数,这种函数在被测试代码更新或局部输入代码修改或测试驱动代码修改时很容易导致编译链接错误且难以处理。
发明内容
本发明要解决的技术问题是,提供一种支持表格驱动局部输入和/或局部输出的单元测试系统和方法,消除前述的现有技术的缺陷。为了解决上述技术问题,本发明提出的技术方案是:
一种支持表格驱动局部数据的单元测试系统,所述局部数据包括局部输入和/或局部输出,其特征在于,包括:
A:类型解析装置,用于解析数据类型定义获得类型信息;
B:树表装置,由树形控件和表格控件组成,用于树状显示变量及其成员,并提供表格供用户填写测试用例的输入值和/或输出值;
C:赋值比较装置,包括赋值装置和/或比较装置,所述赋值装置用于将所述树表装置中的所述输入值赋给变量;所述比较装置用于将所述树表装置中的所述输出值与变量的实际值进行比较,并输出测试失败信息;所述变量的数据类型包括基本类型和复合类型;
D:局部数据设定装置,用于供用户指定局部输入变量及其输入位置和/或局部输出变量及其输出位置,并将所述局部输入变量和/或局部输出变量加入装置B,及在所述输入位置插入赋值代码和/或在所述输出位置插入比较代码,所述局部输入变量和/或局部输出变量的数据类型包括基本类型和复合类型,所述输入位置或所述输出位置位于被测试代码中,所述赋值代码用于调用所述赋值装置,所述比较代码用于调用所述比较装置。
装置D还可以包括:删除用户选中的代码或删除赋值操作符的右边表达式,还可以进一步包括:将静态关键字替换为空。
一种支持表格驱动局部数据的单元测试方法,所述局部数据包括局部输入和/或局部输出,其特征在于,包括以下步骤:
A:类型解析步骤,用于解析数据类型定义获得类型信息;
B:树表步骤,所述树表由树形控件和表格控件组成,用于树状显示变量及其成员,并提供表格供用户填写测试用例的输入值和/或输出值;
C:赋值比较步骤,包括赋值步骤和/或比较步骤,所述赋值步骤用于将所述树表中的所述输入值赋给变量;所述比较步骤用于将所述树表中的所述输出值与变量的实际值进行比较,并输出测试失败信息;所述变量的数据类型包括基本类型和复合类型;
D:局部数据设定步骤,用于供用户指定局部输入变量及其输入位置和/或局部输出变量及其输出位置,并将所述局部输入变量和/或局部输出变量加入所述树表,及在所述输入位置插入赋值代码和/或在所述输出位置插入比较代码,所述局部输入变量和/或局部输出变量的数据类型包括基本类型和复合类型,所述输入位置或所述输出位置位于被测试代码中,所述赋值代码用于调用所述赋值步骤,所述比较代码用于调用所述比较步骤。
步骤D还可以包括:删除用户选中的代码或删除赋值操作符的右边表达式,还可以进一步包括:将静态关键字替换为空。
另外,本发明还提出了前述支持表格驱动局部数据的单元测试系统的次佳方案,其特征在于,用特征E代替特征B:
E:表格装置,用于供用户填写测试用例的输入值和/或输出值。
本发明实现了支持表格驱动局部数据的单元测试系统,不需要额外的测试驱动代码;对于局部输入,不需要额外生成函数;不需要手动将数据移到表格中;数据表格直接支持复合数据类型、空指针、数组的局部输入或局部输出;支持只对变量的部分成员设置局部输入或局部输出;解决现有技术的浅拷贝局部输入有时工作不正常的问题。本发明完全克服了现有技术的主要缺陷,用户不需要编写、调试和维护用于设置局部输入或局部输出的大量的测试驱动代码,更不需要维护额外的局部输入函数,提高了测试数据的可维护性,大幅提升了单元测试效率。
附图说明
下面结合附图对本发明的具体实施方式作进一步详细的说明:
图1是本发明的一个实施例的总体构成示意图;
图2是一些示例数据类型的定义;
图3是使用了图2所示的数据类型的一个示例被测试函数;
图4是图1所示的装置102的应用效果示意图。
图5图6图7是本发明的应用效果与现有技术的比较示意图,其中:
图5是一个被测试函数和调用的关联函数的示例代码;
图6是现有技术下的测试图5所示的代码的用于解决内部数据的表格数据、为局部输入生成的额外函数、及测试驱动代码,其中,图6A是现有技术的表格数据,图6B是现有技术为局部输入生成的额外函数,图6C是现有技术的测试驱动代码;
图7是应用本发明后的测试图5所示的代码的用于解决内部数据的表格数据、及测试驱动代码,其中,图7A是应用本发明后的表格数据,图7B是应用本发明后的测试驱动代码。
具体实施方式
图1是本发明的一个实施例的总体构成示意图,如图1所示,本实施例包括下述装置:类型解析装置101;树表装置102;赋值装置103;局部数据设定装置104。
本发明实际上解决的是三个技术问题:局部输入问题、局部输出问题、局部输入和局部输出问题,即利用本发明时,可以只解决局部输入问题,也可以只解决局部输出问题,或者同时解决局部输入和局部输出问题。为了避免重复叙述,后文均采用同时解决局部输入和局部输出问题的方式来说明。
本发明的示例代码采用C语言或C++语言编写,但不代表本发明只适用于C语言和C++语言。本发明所列举的示例代码仅仅为了便以说明本发明的技术方案,不代表是对本发明的限制。
装置101解析数据类型定义获得类型信息。类型信息属于本领域的通用术语,不同的编程语言,类型信息可能有些差别,一般来说,类型信息包括:类型名称、内存大小,各成员的成员名称、类型名称、偏移量,当然,还可以包含其他信息,如成员函数列表。下面是用于描述类型信息的数据结构的一个示例:
用于描述一个成员,其中:type为成员的类型;name为成员的名称;offset为成员的偏移量。
用于描述一个类型,其中,type为类型名称,size为类型的实例的内存大小,childCount为成员数量,pChilds为成员指针数组。当用于基本类型时,childCount为0,pChilds为NULL。当然,也可以不使用childCount和pChilds,而是使用一个链表或类似的集合来代替。
装置101扫描被测试代码,对各个数据类型的定义进行解析,获得类型信息,可以将类型信息保存在映射表中,供本发明的其他装置查询使用。由于解析过程属于一般的代码解析和编译技术,这里不作更详细的说明。
装置102是一个树表,由树形控件和表格控件组成,用于树状显示变量及其成员,并提供表格供用户填写测试用例的输入值和/或输出值。局部输入也是测试用例的输入,局部输出也是测试用例的输出。利用本发明时,如果只解决局部输入问题,树表可以只提供填写输入值的单元格,如果只解决局部输出问题,树表可以只提供填写输出值的单元格。为了便以说明,后文中树表均使用包括输入值和输出值的方式。树表既可以像一般的树形控件一样,展开到每个叶子结点,或收起一些结点只显示部分结点,也可以像一般的表格控件一样增加不限数量的列,以便填写不限数量的用例。
图2图3图4示出了装置102的应用效果,其中,图2是一些示例数据类型的定义,图3是使用了图2所示的数据类型的一个被测试函数,图4是装置102的应用效果示意图,即针对图3所示的函数,供用户建立测试数据的界面示意图。用户可以选择单元格设置输入和输出值,也可以增加列来建立更多的用例。
对于每一个变量,根据变量的类型查询装置101所获得的类型信息,将该变量加入树表,并递归扫描所有的成员,根据成员的类型名称找到类型信息,将成员作为子结点加入树表,直到基本类型,即树表的子结点均为基本类型,为了方便用户查看各结点的成员及类型,树表的结点可以显示变量名称和类型名称,也可以将对应的类型信息如前述DataType结构的指针保存在结点中,方便后续的操作。表格部分,可以采用一行两列方式,即每个结点对应表格部分的一行,每个用例两列,即输入列和输出列,也可以使用一列两行方式,即每个节点对应表格部分的两行,即输入行和输出行,每个用例占用一列。在后文中引述装置102时,均采用一行两列方式。用户可以通过增加列来建立更多的用例。至于树表控件的实现过程,和将变量加入树表的过程,以及对树表的常规操作过程,属于现有技术,这里不作详述。
装置103包括赋值装置和/或比较装置。如果本发明只应用于解决局部输入问题,只需实现赋值装置,如果只应用于解决局部输出问题,只需实现比较装置,如果应用于同时解决局部输入和局部输出问题,则需要实现赋值装置和比较装置。
赋值装置将树表装置中的输入值赋给变量,变量的数据类型可以是基本类型,也可以是复合类型,即赋值装置用于将基本类型或复合类型的数据,为基本类型或复合类型的变量赋值。由于树表本身是根据变量及其成员的树形关系建立的,树表中的数据,与变量及其成员具有一一对应的关系,赋值装置的实现思路就是根据这种关系进行赋值操作,在总的思路下,可以设计出多种具有不同细节的实现过程。
下面示出一种实现过程,其具体的思路是:递归扫描变量及其成员,对需要初始化的变量或成员初始化,对于对应输入值不为空的变量或成员,拷贝对应输入值;所述对应输入值,是指所述树表装置中,变量或成员对应的当前用例的输入值,例如,树表采用一行两列方式,则对应输入值是指变量或成员对应的行和当前用例的输入列组成的单元格的值,有些对应输入值可能需要经过转换,例如,整数类型,表格中填写的可能是字符串,要转换为整数。例如,针对C或C++语言,下面的步骤可以实现赋值装置:
1)根据变量的类型名称,可以找到对应的类型信息,以及是否为指针或数组。数组可以视为复合类型,如int[10],可以视为含有10个int类型成员的复合类型。
2)将变量设为空值,例如C语言,对于指针,则设为空指针,非指针则调用memset()清空内存。如果变量对应输入值为空,且所有直接和间接成员的对应输入值也为空,则返回。
3)如果变量的类型为指针,且对应输入值为空指针,则设为空指针。返回。
4)变量如果需要自行管理内存,如C或C++的指针,则先申请内存。申请内存的方式视语言而定,如C语言,可以调用malloc(size),而对于C++,则调用new操作符。
5)将对应输入值拷贝到变量的内存中,例如C语言,可以用以下方式拷贝:
字符串:strcpy(pDes,pSrc),其中,pDes为变量或成员的指针,pSrc为对应输入值。
整数int:*((int*)pvar)=value,其中,pvar为变量或成员的指针,value为对应输入值。
其他类型的拷贝方式大同小异,不再一一列举。
6)针对变量的每一个成员,根据成员的偏移量,计算出成员的指针,并递归执行上述步骤。
步骤2)3)4)可以看作是对变量或成员初始化。对变量或成员初始化是本领域的基础技术,不同的编程语言,不同的类型,初始化的过程可能不同。对于不使用指针的语言,不需要申请内存和设置空指针的步骤,这种情形下,对变量或成员的内存初始化,通常只是将内存清空或设为缺省值。
有些语言的有些变量的初始化,可能需要调用构造函数,例如C++语言的含有虚函数的类型,其对象的初始化,最好调用构造函数,以免由于虚函数表不正确影响测试执行过程,这种情形下,可以用下述方法代替步骤4)所述的new操作符:在解析类型信息时建立一个需调用构造函数的类型的列表,并给每个类型分配一个序号,并生成对象生成函数的代码,测试代码开始执行时,将对象生成函数的指针传递给测试工具,对象生成函数的功能是根据类型序号调用类型的构造函数生成对象指针,在对变量初始化时,调用对象生成函数并传递类型编号,从而得到调用构造函数而建立的对象指针。对于支持运行期构造对象的语言,如Java语言,不需要使用这种方式。
可以针对表格数据制定一些规则,例如,对于某些特殊的值,可以约定表示该值的符号,如用NULL表示空指针,本发明的示例中,在树表或表格中,均使用NULL表示空指针。
为了实现上的简便,在上述步骤5),通常只处理基本类型,如果树表允许直接针对复合类型填写复合数据,则这种数据通常是按某些规则编排的数据,如图4所示的单元格401中的数据,对于这种情形,在执行赋值过程前,可以将数据分解并分配到叶子结点对应的单元格,即基本类型的成员对应的单元格,以便使步骤5)只处理基本类型。
比较装置用于将树表装置中的输出值与变量的实际值进行比较,并输出测试失败信息,变量的数据类型可以是基本类型,也可以是复合类型,比较装置用于将基本类型或复合类型的数据,与基本类型或复合类型的变量比较。由于树表本身是根据变量及其成员的树形关系建立的,树表中的数据,与变量及其成员具有一一对应的关系,比较装置的实现思路就是根据这种关系进行比较,在总的思路下,可以设计出多种具有不同细节的实现过程。
下面示出一种实现过程,其具体的思路是:递归扫描变量及其成员,对于对应输出值不为空的变量或成员,比较实际值与对应输出值,如比较结果为假,则输出测试失败信息;所述对应输出值,是指所述树表装置中,变量或成员对应的当前用例的输出值,例如,树表采用一行两列方式,则对应输出值是指变量或成员对应的行和当前用例的输出列组成的单元格的值,有些对应输出值可能需要经过转换,例如,整数类型,表格中填写的可能是字符串,要转换为整数。例如,针对C或C++语言,下面的步骤可以实现装置104:
1)根据变量的类型名称,可以找到对应的类型信息,以及是否为指针或数组。数组可以视为复合类型,如int[10],可以视为含有10个int类型成员的复合类型。指针可以视为一个特殊的int类型变量,需要先比较判断空指针,再视具体情况决定是否进行指针所指对象的比较。
2)如果变量的对应输出值为空,且所有直接和间接成员的对应输出值也为空,则返回。
3)如果变量的数据类型为指针,且对应输出值为空指针,则判断实际值是否为空指针,如果不是,则输出测试失败信息,如“pData expect NULL but not”。返回。
4)如果变量的类型是指针,且实际值为空指针,而对应输出值不是空指针,或某些直接或间接成员的对应输出值不为空,则输出测试失败信息,如“pData->a expect123but pData is NULL”。返回。
5)将变量的实际值与对应输出值进行比较,例如C语言,可以用以下方式比较:
字符串:strcmp(pDes,pSrc)==0,其中,pDes为变量的指针,pSrc为对应输出值。
整数int:*((int*)pvar)==value,其中,pvar为变量的指针,value为对应输出值。
其他类型的比较方式大同小异,不再一一列举。如果对应输出值使用了操作符,如&0x00FF00,则要生成判断表达式,如(*((int*)pvar))&0x00FF00,然后计算表达式的值,如果计算结果为假,则视为比较的结果为假。计算表达式的值的过程属于现有技术,这里不作详述。
如果比较结果为假,则输出测试失败信息,如“pData->a expect123but124”。
6)针对变量的每一个成员,根据成员的偏移量,计算出成员的指针,并递归执行上述步骤。
对于不使用指针的语言,不需要判断和比较空指针的步骤。
为了实现上的简便,在上述步骤5),通常只处理基本类型,如果树表允许直接针对复合类型填写复合数据,可以参照赋值装置的说明,使步骤5)只处理基本类型。
装置104是局部数据设定装置,用于供用户指定局部输入变量及其输入位置和/或局部输出变量及其输出位置,并将局部输入变量和/或局部输出变量加入装置B,及在输入位置插入赋值代码和/或在输出位置插入比较代码,局部输入变量和/或局部输出变量的数据类型包括基本类型和复合类型,输入位置或输出位置位于被测试代码中,赋值代码用于调用赋值装置,比较代码用于调用比较装置。
以下是装置104的一个实施例的实现步骤:
a.用户在被测试代码中选择局部输入或局部输出位置。一种实现方式是提供一个显示被测试代码的界面,用户通过单击选择局部输入或局部输出位置。
b.用户指定局部输入或局部输出变量。一种实现方式是弹出一个界面,供用户填写局部输入变量或局部输出变量的变量名称。变量的类型可以由用户填写,也可能通过解析被测试代码获得。
c.将用户指定的局部输入或局部输出变量加入树表。
d.在步骤a所指定的位置上插入赋值代码或比较代码。
赋值代码用于调用赋值装置。赋值装置的功能是将树表中的用例输入值赋给变量。下面是赋值代码的一个实现示例:
extern void*_LocalInput(const char*type,const char*name,void*pDes);
#define_ASSIGNI_(t,n)_LocalInput(#t,#n,&n)
函数_LocalInput()可以由应用了本发明的测试工具提供,是赋值装置的一种实现,该函数有三个参数,分别是变量的类型、变量名称、变量的地址,其中,变量类型可以从树表中查询,因此可省略。插入赋值代码到被测试代码时,使用_ASSIGNI_宏可以更简洁些,例如,用户要对MyData类型的变量data设置局部输入,那么,在步骤a所指定的位置插入_ASSIGNI_(MyData,data)即可。
比较代码用于调用比较装置。比较装置的功能是将树表中的用例输出值与变量的实际值进行比较,并输出测试失败信息。下面是比较代码的一个实现示例:
extern void_LocalOutput(const char*type,const char*name,void*pDes);
#define_OUTPUT_(t,n)_LocalOutput(#t,#n,&n)
函数_LocalOutput()可以由应用了本发明的测试工具提供,是比较装置的一种实现,该函数有三个参数,分别是变量的类型、变量名称、变量的地址,其中,变量类型可以从树表中查询,因此可省略。插入比较代码到被测试代码时,使用_OUTPUT_宏可以更简洁些,例如,用户要对MyData类型的变量data设置局部输出,那么,在步骤a所指定的位置插入_OUTPUT_(MyData,data)即可。
对于局部输入,有些情形下,可以使用替换代码来代替插入,即在插入时删除指定的代码,例如,被测试代码行:
int m=*(ga.b.parr[index])*arg;
要将其中的*(ga.b.parr[index])设为局部输入变量,这是int类型表达式,用户可以指定插入位置为表达式*(ga.b.parr[index])的起始位置,即选中这个表达式,在插入赋值代码的同时,删除该表达式,变成:
int m=_ASSIGNI_(int,*(ga.b.parr[index]))*arg;
替换代码还可以解决有些关联代码在测试过程中导致测试中断的问题,例如,从界面读取输入的代码,可能因为界面资源在单元测试环境下不存在而导致测试过程崩溃,这时,将涉及界面的代码替换为局部输入的赋值代码,既可以解决界面输入问题,也可以解决界面代码崩溃的问题。
对于使用赋值操作符进行赋值的变量,还可以进一步提供简便的操作,即直接替换赋值操作符右边的表达式,要实现此功能,装置104可以对插入位置前后的代码进行分析,找出操作符右边表达式的开始和结束位置,并替换。
对于局部静态变量,设置为局部输入变量后,最好将静态关键字,如C/C++语言的static替换为空,使该变量不再是静态变量,并在表格中控制其值。
下面是本发明的一个实施例的具体工作过程:
装置101解析类型信息供其他装置使用。用户通过装置104,设置局部输入或局部输出变量,自动添加到装置102中,并自动在被测试代码中插入赋值代码或比较代码。用户在装置102中对局部输入变量设置输入值或对局部输出变量设置预期的输出值。测试执行过程中,赋值代码调用装置103中的赋值装置对局部输入变量进行赋值或调用装置103中的比较装置对局部输出变量的实际值与用户设置的预期值进行比较,并输出测试失败信息。
图5图6图7是本发明的应用效果与现有技术的比较示意图,其中:图5是一个被测试函数和调用的关联函数的示例代码;图6是现有技术下的测试图5所示的代码的用于解决内部数据的表格数据、为局部输入生成的额外函数、及测试驱动代码,其中,图6A是现有技术的表格数据,图6B是现有技术为局部输入生成的额外函数,图6C是现有技术的测试驱动代码;图7是应用本发明后的测试图5所示的代码的用于解决内部数据的表格数据、及测试驱动代码,其中,图7A是应用本发明后的表格数据,图7B是应用本发明后的测试驱动代码。
如图5所示,函数mysub()是关联函数,函数local_input_output_test()是被测试函数。如图6A和图7A所示,现有技术和应用本发明的示例,需要设定的局部输入和局部输出数据相同或相似,如图7B所示,利用本发明,设置局部输入或局部输出时测试驱动代码并未修改,不需要增加额外的代码,也不需要增加额外的函数,如图6B所示,现有技术使用了额外的函数,如图6C所示,现有技术需要添加大量的测试驱动代码,图6C中,第2至第14行共13行代码,均为设置局部输入的代码,其中,仅有第14行由工具生成,其他均需要手工编写,并需手工将数据移到表格中,如图6C所示,第16至第19行共4行代码为局部输出代码,即用于判断局输出变量是否符合预期的代码,这些代码需要人工编写,并手工将数据移到表格中。从图6和图7的比较可以看出,利用本发明,可以避免编写、调试和维护大量的测试驱动代码,也不需要添加额外的函数,仅此一项,就可以大幅提升单元测试的效率。
对于本发明所述的支持表格驱动局部数据的单元测试方法,其实现步骤已包含于前面的说明中,不再重复。
本发明可以不使用树表装置102,而用一般的表格来代替。这是一种次佳方案,也能实现本发明的主要效果,但是,使用表格方式,要么将变量及其所有直接或间接成员全部加入表格,要么只加入变量本身而不加入成员,当数据类型很复杂时,这两种方式对用户都不方便,前者造成表格中行数太多,特别是对于含有指向自身指针的成员的类型,可能造成死循环,后者则填写数据的难度较大。如果采用将变量及其所有直接或间接成员全部加入表格的方式,那么,实施本发明的过程,除装置102部分改为使用表格,其他装置的实施方式是一样的。如果采用只加入变量本身而不加入成员的方式,那么,可以将单元格中的复合数据分解为基本类型的数据,如图4所示的单元格401中的数据,可以先分解成基本类型的数据,这些分解后的数据,与变量的成员是对应的,装置103的赋值装置或比较装置仍然可以按前述的方式进行赋值或比较。
以上实施例仅是本发明的较佳实施方式,仅用以说明本发明而非限制,对本发明进行修改、变形或者等同替换而不脱离本发明的精神和范围,均应涵盖于本发明的范围之内。
Claims (10)
1.一种支持表格驱动局部数据的单元测试系统,所述局部数据包括局部输入和/或局部输出,其特征在于,包括:
A:类型解析装置,用于解析数据类型定义获得类型信息;
B:树表装置,由树形控件和表格控件组成,用于树状显示变量及其成员,并提供表格供用户填写测试用例的输入值和/或输出值;
C:赋值比较装置,包括赋值装置和/或比较装置,所述赋值装置用于将所述树表装置中的所述输入值赋给变量;所述比较装置用于将所述树表装置中的所述输出值与变量的实际值进行比较,并输出测试失败信息;所述变量的数据类型包括基本类型和复合类型;
D:局部数据设定装置,用于供用户指定局部输入变量及其输入位置和/或局部输出变量及其输出位置,并将所述局部输入变量和/或局部输出变量加入装置B,及在所述输入位置插入赋值代码和/或在所述输出位置插入比较代码,所述局部输入变量和/或局部输出变量的数据类型包括基本类型和复合类型,所述输入位置或所述输出位置位于被测试代码中,所述赋值代码用于调用所述赋值装置,所述比较代码用于调用所述比较装置。
2.根据权利要求1所述的单元测试系统,其特征在于,所述类型信息包括:类型名称、内存大小,各成员的成员名称、类型名称、偏移量。
3.根据权利要求1所述的单元测试系统,其特征在于,所述赋值装置包括:递归扫描变量及其成员,对需要初始化的变量或成员初始化,对于对应输入值不为空的变量或成员,拷贝对应输入值;所述对应输入值,是指所述树表装置中,变量或成员对应的当前用例的输入值;所述比较装置包括:递归扫描变量及其成员,对于对应输出值不为空的变量或成员,比较实际值与对应输出值,如比较结果为假,则输出测试失败信息;所述对应输出值,是指所述树表装置中,变量或成员对应的当前用例的输出值。
4.根据权利要求1所述的单元测试系统,其特征在于,所述局部输入变量或局部输出变量包括以下变量之一或以下变量的任意组合或以下变量的一部分:参数、全局变量、成员变量、局部变量、表达式。
5.根据权利要求1至4任一权利要求所述的单元测试系统,其特征在于,装置D进一步包括以下步骤之一:
删除用户选中的代码;
删除赋值操作符的右边表达式。
6.根据权利要求5所述的单元测试系统,其特征在于,装置D进一步包括:将静态关键字替换为空。
7.一种支持表格驱动局部数据的单元测试方法,所述局部数据包括局部输入和/或局部输出,其特征在于,包括以下步骤:
A:类型解析步骤,用于解析数据类型定义获得类型信息;
B:树表步骤,所述树表由树形控件和表格控件组成,用于树状显示变量及其成员,并提供表格供用户填写测试用例的输入值和/或输出值;
C:赋值比较步骤,包括赋值步骤和/或比较步骤,所述赋值步骤用于将所述树表中的所述输入值赋给变量;所述比较步骤用于将所述树表中的所述输出值与变量的实际值进行比较,并输出测试失败信息;所述变量的数据类型包括基本类型和复合类型;
D:局部数据设定步骤,用于供用户指定局部输入变量及其输入位置和/或局部输出变量及其输出位置,并将所述局部输入变量和/或局部输出变量加入所述树表,及在所述输入位置插入赋值代码和/或在所述输出位置插入比较代码,所述局部输入变量和/或局部输出变量的数据类型包括基本类型和复合类型,所述输入位置或所述输出位置位于被测试代码中,所述赋值代码用于调用所述赋值步骤,所述比较代码用于调用所述比较步骤。
8.根据权利要求7所述的单元测试方法,其特征在于,步骤D进一步包括以下步骤之一:
删除用户选中的代码;
删除赋值操作符的右边表达式。
9.根据权利要求8所述的单元测试方法,其特征在于,步骤D进一步包括:将静态关键字替换为空。
10.一种根据要求1所述的单元测试系统,其特征在于,用特征E代替特征B:
E:表格装置,用于供用户填写测试用例的输入值和/或输出值。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201310714445.1A CN104731700B (zh) | 2013-12-20 | 2013-12-20 | 一种支持表格驱动局部数据的单元测试系统和方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201310714445.1A CN104731700B (zh) | 2013-12-20 | 2013-12-20 | 一种支持表格驱动局部数据的单元测试系统和方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN104731700A true CN104731700A (zh) | 2015-06-24 |
CN104731700B CN104731700B (zh) | 2018-11-09 |
Family
ID=53455610
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201310714445.1A Active CN104731700B (zh) | 2013-12-20 | 2013-12-20 | 一种支持表格驱动局部数据的单元测试系统和方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN104731700B (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108549531A (zh) * | 2018-04-19 | 2018-09-18 | 携程旅游网络技术(上海)有限公司 | 复杂类型数据自动生成方法、装置、电子设备、存储介质 |
WO2023272606A1 (zh) * | 2021-06-28 | 2023-01-05 | 东莞市小精灵教育软件有限公司 | 一种树形表格控件生成方法、装置、设备及存储介质 |
Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1873626A (zh) * | 2005-06-01 | 2006-12-06 | 中兴通讯股份有限公司 | 一种自动生成桩和驱动函数的单元测试系统及方法 |
CN1983209A (zh) * | 2005-12-14 | 2007-06-20 | 中兴通讯股份有限公司 | 一种软件单元测试自动化系统及其方法 |
CN101110024A (zh) * | 2007-08-14 | 2008-01-23 | 中兴通讯股份有限公司 | 一种单元测试系统和方法 |
US20080115114A1 (en) * | 2006-11-10 | 2008-05-15 | Sashank Palaparthi | Automated software unit testing |
CN100543699C (zh) * | 2007-07-20 | 2009-09-23 | 中兴通讯股份有限公司 | 针对局部模块的单元测试方法 |
US7844951B2 (en) * | 2005-12-30 | 2010-11-30 | Microsoft Corporation | Specification generation from implementations |
-
2013
- 2013-12-20 CN CN201310714445.1A patent/CN104731700B/zh active Active
Patent Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1873626A (zh) * | 2005-06-01 | 2006-12-06 | 中兴通讯股份有限公司 | 一种自动生成桩和驱动函数的单元测试系统及方法 |
CN1983209A (zh) * | 2005-12-14 | 2007-06-20 | 中兴通讯股份有限公司 | 一种软件单元测试自动化系统及其方法 |
US7844951B2 (en) * | 2005-12-30 | 2010-11-30 | Microsoft Corporation | Specification generation from implementations |
US20080115114A1 (en) * | 2006-11-10 | 2008-05-15 | Sashank Palaparthi | Automated software unit testing |
CN100543699C (zh) * | 2007-07-20 | 2009-09-23 | 中兴通讯股份有限公司 | 针对局部模块的单元测试方法 |
CN101110024A (zh) * | 2007-08-14 | 2008-01-23 | 中兴通讯股份有限公司 | 一种单元测试系统和方法 |
Non-Patent Citations (2)
Title |
---|
WANGWENCONG: ""用局部数据模拟进一步解决单元测试的内部输入"", 《HTTPS://BLOG.CSDN.NET/WANGWENCONG/ARTICLE/DETAILS/8285505》 * |
张秀琼: ""ATC系统软件自动化单元测试工具的研究与实现"", 《万方数据》 * |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN108549531A (zh) * | 2018-04-19 | 2018-09-18 | 携程旅游网络技术(上海)有限公司 | 复杂类型数据自动生成方法、装置、电子设备、存储介质 |
WO2023272606A1 (zh) * | 2021-06-28 | 2023-01-05 | 东莞市小精灵教育软件有限公司 | 一种树形表格控件生成方法、装置、设备及存储介质 |
Also Published As
Publication number | Publication date |
---|---|
CN104731700B (zh) | 2018-11-09 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN101770363B (zh) | 将可执行代码转换为不同编程语言的方法及设备 | |
CN107590319B (zh) | 一种用于机械产品方案辅助设计的知识建模方法和系统 | |
US8150673B1 (en) | Partitioning a model in modeling environments | |
CN104778124B (zh) | 一种软件应用自动化测试方法 | |
CN110149800B (zh) | 一种用于处理与源程序的源代码相关联的抽象语法树的装置 | |
US9880922B1 (en) | System and method for automatically generating a graphical model from a text-based program | |
EP1089172A2 (en) | Compiler and method for compiling specification language into implementation language | |
CN111324647A (zh) | 一种生成etl代码的方法及装置 | |
US9904524B2 (en) | Method and device for visually implementing software code | |
CN109254905B (zh) | 基于工作流的分布式并行自动化测试系统 | |
CN110221975B (zh) | 创建接口用例自动化测试脚本的方法及装置 | |
CN104714881B (zh) | 一种表格驱动的单元测试系统和方法 | |
US10216501B2 (en) | Generating code in statically typed programming languages for dynamically typed array-based language | |
CN109739740A (zh) | 一种aadl模型组合形式化验证方法 | |
CN106325860A (zh) | 一种航天嵌入式软件接口数据的自动化维护方法 | |
CN114926151A (zh) | 一种基于强化学习的rpa流程自动生成方法和装置 | |
Handley et al. | Maintaining the consistency of sysml model exports to XML metadata interchange (XMI) | |
CN104731700A (zh) | 一种支持表格驱动局部数据的单元测试系统和方法 | |
CN104731695B (zh) | 一种支持表格驱动底层输入的单元测试系统和方法 | |
KR100994070B1 (ko) | 예약된 컴포넌트 컨테이너 기반 소프트웨어 개발 방법 및장치 | |
CN112148271B (zh) | 一种装配工艺代码自动生成与注入的方法 | |
CN106094561B (zh) | 船舶综合电力推进系统建模仿真方法及装置 | |
CN109902085A (zh) | 一种配置存储结构优化方法及系统 | |
CN204360367U (zh) | 代码自动生成装置 | |
Rodríguez-Echeverría et al. | IFML-based Model-Driven Front-End Modernization |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
CB02 | Change of applicant information |
Address after: 510315 UP Chi Chi C2-209, 29, West Road, Hongwei new village, Haizhuqu District, Guangzhou, Guangdong. Applicant after: Guangzhou Kaile Software Technology Co., Ltd. Address before: 510630 303, room 244, five mountain road, Tianhe District, Guangzhou, Guangdong. Applicant before: Guangzhou Kaile Software Technology Co., Ltd. |
|
CB02 | Change of applicant information | ||
GR01 | Patent grant | ||
GR01 | Patent grant |