基于WEHG模型的GUI软件测试用例生成方法
2018-05-09向日锋毛宇光
向日锋,毛宇光
(南京航空航天大学计算机科学与技术学院,江苏 南京 211106)
0 引 言
随着信息技术的飞速发展,计算机软件深入社会中的航天、零售、医疗、金融、汽车等各个领域。但是,在软件的设计、开发等阶段都可能引入错误从而导致软件功能部分或者整体失效,甚至引发严重的生产安全问题,这使得软件质量也不得不受到人们的关注。
软件测试是保证软件可靠性的重要手段,能够有效地保证产品的质量。GUI测试是一个新的测试研究领域,随着GUI应用的快速发展,GUI测试的研究却相对滞后,这对整个软件开发和测试过程都有着不可估量的影响。测试用例生成问题是GUI测试的核心所在,同时,因为GUI的图形界面特点和巨大的状态空间,使得测试评判的生成也存在诸多难点,所以研究针对GUI测试特有的测试用例生成和测试评判生成方法有极其重要的意义。
在生成GUI测试用例的过程中,有一个很重要的环节,就是对GUI软件进行行为建模。事件流图(Event Flow Graph, EFG)是一种常见的基于行为模型的GUI测试方法。EFG模型中节点表示事件,有向边表示事件之间的发生先后关系,根据相邻节点的序列长度制定测试覆盖准则,结合EFG模型生成测试用例。该模型最早是由Memon[1]在对GUI测试的覆盖率研究时提出的,建立该模型的目的是为了更好地描述GUI中对象的事件和事件之间的交互关系。但是EFG模型只关注事件以及事件之间的交互,没有关注事件所对应的事件处理函数的代码结构以及事件处理函数之间的代码依赖关系,导致生成的测试用例代码覆盖率不高,同时还会生成很多的无效测试用例。对于事件体积量不断增大的GUI软件,生成的测试用例数量呈指数级增长,大大制约了GUI软件的测试效率[2]。
在EFG模型的基础上,陈军成[3-4]等人提出了基于事件处理函数模型(Event-Hander Function Graph, EHG)的GUI测试方法。EHG中节点表示事件处理函数,有向边表示事件处理函数被触发的先后关系。根据事件处理函数的代码结构以及事件处理函数之间的代码依赖关系制定测试覆盖准则[5],结合EHG模型生成测试用例。EHG和EFG相比较,主要作了2方面的改进,一方面清晰地表述了代码交互事件和默认事件的关系,不会生成没有事件组合意义的无效测试用例,另一方面EHG模型要比EFG模型小,在控件越多的GUI软件上尤为明显。
一些事件对应的事件处理函数包含了较多的变量,或者事件处理函数之间的定义-引用对较多,包含越多这样的事件的测试用例就越容易发现软件的缺陷。基于EHG模型的测试方法未考虑到事件的权重值以及事件之间的依赖关系,这会导致在测试用例集数量较为庞大的条件下GUI软件缺陷检测的效率降低。本文提出一种基于带权重的事件处理函数模型(Event-Hander Graph based on Weight, WEHG)的GUI测试方法。WEHG和EHG相比较,主要作了2方面的改进,一方面根据事件处理函数中定义变量和引用变量的数量和给对应的节点设置权重值,从而保证拥有更多变量的节点能够优先生成测试用例,另一方面根据事件处理函数的定义-引用对给节点之间的依赖关系设置依赖值,使依赖度高的节点能够优先加入测试序列中。通过该方法生成具有优先级排序的测试用例集,在版本更新较快或者窗体界面较多的GUI软件中能够生成针对性更强的测试用例集,并且优先执行能更快发现软件缺陷的测试用例,提高软件测试的效率。
1 GUI模型
1.1 相关定义
下面给出一些关于行为模型的定义,以便理解本文提出的基于WEHG模型的GUI软件测试用例生成方法。
定义1GUI状态。假设应用程序包括n个GUI窗体类w1,w2,…,wn和m个非窗体类静态数据成员sd1,sd2,…,sdm,窗体类wi的k个数据成员DMwi={mvi1,mvi2,…,mvik} (0
定义2GUI事件。GUI事件是一个三元组:operator(evtName,precondition,effect),其中,evtName表示GUI事件的名称及参数,precondition表示GUI事件发生的前提条件,effect表示GUI事件发生后的GUI状态[6]。
定义3GUI变量。GUI变量包括GUI状态变量、GUI控件变量、内部变量。其中窗体类数据成员和非窗体类静态数据成员称为GUI状态变量。GUI窗体类中,声明的GUI控件数据成员称为GUI控件变量,其他非GUI控件变量的GUI状态变量称为GUI内部变量[3]。
定义4GUI事件处理函数。事件处理函数为一个三元组,其形式为ehf(se,source,ue)。其中,se表示触发事件处理函数ehf执行的代码交互事件集合。source表示ehf所对应的事件处理函数的函数体,利用此信息可以分析事件处理函数的控制流图、数据流图等信息。ue表示ehf执行时,接收的默认事件集合[7]。
定义5GUI事件依赖。GUI事件依赖[5]是一个三元组:dependent(u,e0,e1),其中,e0和e1表示待测软件中的2个GUI事件,u表示e0和e1之间的依赖度,由e0和e1对应事件处理函数中的GUI变量决定。
定义6事件处理函数的定义-引用对。若事件处理函数ehf1和事件处理函数ehf2出现在同一个测试用例t中,存在一个GUI变量v在事件处理函数ehf1某条语句中被定义,在另一个事件处理函数ehf2某条语句中被使用到,那么称(ehf1,ehf2,v)是测试用例t中关于变量v的事件处理函数的定义-引用对。
1.2 基于事件流图EFG的行为模型
建立事件流图EFG模型的目的是通过模拟窗体内的事件和事件之间的交互关系来生成满足测试需求的测试用例集[2,8]。由一个三元组M=(E,R,I)组成,EFG中节点的集合E表示GUI中的事件,边的集合R,即有序对(ex,ey)的集合,其中ex∈E, ey∈E,且(ex,ey)∈R,表示事件执行的先后关系。I⊆R表示初始状态下的事件集合,即刚启动软件用户可以执行的事件集合。
1.3 基于事件处理函数EHG的行为模型
事件处理函数图EHG模型由一个二元组EHG(V,E)组成,V表示事件处理函数集合,E表示V中元素对的有穷集合,即有序对(nx,ny)的集合,其中nx∈V, ny∈V,且(nx,ny)∈E,则事件处理函数nx执行之后,可以执行事件处理函数ny。
1.4 基于带权重的事件处理函数WEHG的行为模型
带权重的事件处理函数图WEHG由一个四元组EHG(V,E,ψ,Ω)组成,V表示事件处理函数集合,E表示V中元素对的有穷集合,即有序对(nx,ny)的集合,其中nx∈V, ny∈V,且(nx,ny)∈E,则事件处理函数nx执行之后,可以执行事件处理函数ny。ψ表示图中所有有向边的依赖度集合,边(nx,u,ny)∈ψ表示节点之间的依赖关系。u∈N+表示e和e′之间的依赖度,Ω表示事件处理函数的权重值集合。
2 测试用例集的生成方法
2.1 测试用例生成框架
为了解决大量的测试用例无法尽快找到软件缺陷的问题,本文提出一种基于带权重的事件处理函数模型生成GUI软件测试用例的方法对GUI软件建模。其基本流程如下:
1)利用Windows操作系统提供的微软用户界面自动化(User Interface Automation, UIA)框架识别待测软件(Application Under Test, AUT)中的所有控件以及控件的属性,通过UIA提供的接口驱动AUT执行,并生成该AUT的EFG模型。
2)利用Roslyn工具对AUT源代码进行静态分析,获得所有事件处理函数之间的定义-引用对,根据定义-引用对给所有控件设置权重,在控件之间设置依赖度大小值,生成WEHG模型。
3)利用WEHG模型生成抽象的测试用例集。
4)将抽象的测试用例集每一个测试用例结合EFG模型生成完整的测试用例。
在上述步骤中,WEHG模型中节点之间的依赖关系和节点的权重值是指导测试用例生成的重要信息。本文接下来主要介绍构造WEHG模型的算法以及基于WEHG模型的GUI测试用例生成算法。
2.2 WEHG模型构造算法
算法1描述了WEHG模型的构造过程,它的输入是待测软件AUT和EHG模型(V,E),输出是WEHG模型(V′,E′,ψ,Ω),该算法的事件复杂度是O(n2),空间复杂度是O(1)。
算法1构造WEHG模型
输入:AUT,EHG模型(V,E)
输出:WEHG模型(V′,E′,ψ,W)
1. E′=E
2. V′=V //将EHG模型中节点和节点间的关系传给WEHG模型
3. W={ }, R={ }, R′={ }
4. for each (e in E) do //给每个节点设置权重
5. W=getFieldsWritten(e,AUT)
6. R=getFieldsRead(e,AUT)
7. ω=|W∪R|
8. Ω=Ω∪(e,ω)
9. for each (e′ in E) do //给相关联节点设置依赖度
10. R′=getFieldsRead(e′,AUT)
11. if (W∩R′≠Φ) then
12. u=|W∪R′|
13. ψ=(e,u,e′)
14. end if
15. end for
16. end for
2.3 WEHG模型生成抽象测试用例算法
算法2描述了基于WEHG模型生成抽象测试用例的过程,它的输入是WEHG模型(V′,E′,ψ,Ω),抽象测试用例最大长度len,每个头节点可产生的测试用例的最大数目top,输出是抽象测试用例集П。该算法的事件复杂度是O(n3),空间复杂度是O(1)。
算法2生成抽象测试用例
输入:WEHG模型(V′,E′,ψ,Ω),抽象测试用例最大长度len,每个头节点可产生的测试用例的最大数目top
输出:抽象测试用例集П
1. П={}
/*将所有节点作为抽象测试用例第一个节点遍历生成测试用例*/
2. while Ω≠Φ do
3. e=Max((e,ω),Ω)//优先选择权重大的节点
4. Ω=Ω-(e,ω)
5. Queue of abstract test cases П′={}
6. ψ′=ψ
7. while |П′| 8. Sequence of events π=e 9. Event e′=e 10. while |π| //查找和当前节点依赖度最大的节点加入当前抽象测试用例中 11. do 12. e′=Max((e,u,e′),ψ′) 13. π=π*e′ 14. end while 15. П′=П′∪π 16. end while 17. П=П+П′ 18. end while 19. return П 算法3描述了结合EFG模型和算法2生成的抽象测试用例集生成可执行测试用例的过程,它的输入是EFG模型(E,I,δ)和抽象测试用例集П,输出是可执行测试用例集T,该算法的事件复杂度是O(n2),空间复杂度是O(1)。 算法3生成可执行测试用例 输入:EFG模型(E,I,δ),抽象测试用例集П 输出:可执行测试用例集T 1. Sequences of events T={} /*对于抽象测试用例集П中所有测试用例进行遍历生成可执行的测试用例*/ 2. for each tc in П do 3. for each Sequence ei,…,ejin tc do /*在EFG模型中查找当前测试用例中每一个节点的可达路径*/ 4. pick e0from I 5. Path tc=shortestPath(e0,ei) 6. for k=i to j-1 do 7. tc=tc*shortestPath(ek,ek+1) 8. end for 9. end for 10.T=T∪{tc}//将生成的测试用例加入可执行测试用例集T中 11. end for 12. return T 为了验证提出的基于WEHG模型的GUI软件测试用例生成方法的有效性,本文设计并实现了基于UIA框架和Roslyn的GUI测试工具[9],其中Roslyn主要是对窗体上控件的源代码进行静态分析,UIA框架可获得所有控件的详细信息,并将控件之间的关系以树形图表示,同时可使用UIA框架提供的接口驱动被测软件的执行。 本文实验选用的待测软件是很多GUI测试研究都选用的Notepad记事本软件,该软件是由C#实现的开放源代码的程序,虽然控件规模比较小,但是有很丰富的控件类型,GUI对象之间的关系也比较复杂,具有一定的代表性,适合缺陷注入和测试。为了充分测试该方法的缺陷侦测效率,并且尽量使缺陷的类型多样化,给该待测软件注入了10个缺陷[10],如表1所示。 表1 缺陷注入列表 注入位置缺陷描述菜单选项FileFile选项展开后缺少SaveAs选项Save选项快捷键未设置Gore>Bush>NaderNader>Gore>Bush菜单选项Edit的子选项Cut选中文字后,剪切操作无效Font设置字体设置无效About窗口中的Label单词“Programmed”拼写错误About窗口中的OK按钮OK状态变为Disable将OK按钮的功能设置为Cancel按钮的功能Help菜单选项的Register子选项期望的Register对话框没有弹出 本实验全部在Windows 7操作系统上进行,硬件平台为Intel Core i3-3110 2.4 GHz双核,4 GB RAM。 本文为了测试用例生成方法的需要和对生成测试用例性能的评判,定义2个GUI测试用例评价准则。 定义7事件处理函数覆盖准则。程序中的每一个事件处理函数对应的事件至少被执行一次,即WEHG模型中每个节点至少被覆盖一次。 使用事件处理函数覆盖率来评判测试用例集的事件处理函数覆盖情况,计算公式为: 其中,NODE(ST)表示测试用例集ST所覆盖的WEHG模型中顶点的集合,NG表示事件WEHG模型中所有顶点的集合。 定义8事件处理函数交互覆盖准则。检查模型中可能的事件处理函数之间的交互关系,要求当事件处理函数nx执行后,可执行的事件处理函数ny至少被执行一次,即WEHG模型中每条有向边至少被覆盖一次。 使用事件处理函数交互覆盖率来评判测试用例集的事件处理函数的定义-引用对覆盖情况,计算公式为: 其中,EDGE(ST)表示测试用例集ST所覆盖的WEHG模型中有向边的集合,EG表示WEHG模型中所有有向边的集合。 表2给出了待测软件Notepad在EFG模型、EHG模型以及WEHG模型中的规模,此外,通过Roslyn工具静态分析得到待测软件Notepad的事件处理函数定义-引用对个数为55。 表2 Notepad的EFG,EHG和WEHG规模 模型类型节点数/个边数/条EFG34896EHG/WEHG29677 本次实验基于EFG模型共生成692个测试用例,其中有32个无效测试用例,基于EHG模型和WEHG模型各生成386个测试用例,其中基于WEHG模型生成的测试用例做了优先级排序。基于3种模型生成的前50个测试用例中事件处理函数的覆盖情况如图1所示,可以看到,在执行相同数目的测试用例的时候,基于EFG模型生成的测试用例事件处理函数覆盖率最低,基于EHG模型生成的测试用例事件处理函数覆盖率次之,而基于WEHG模型生成的测试用例对事件处理函数的覆盖效率最高,在执行到第43个测试用例时就已经覆盖了所有的事件处理函数。本次实验说明了基于WEHG模型生成的测试用例能最快地执行所有的事件处理函数,当单个事件处理函数对应的事件本身有缺陷时,使用本文提出的方法能够尽快地发现缺陷。 图1 前50个测试用例事件处理函数覆盖率的变化图 图2反映了执行基于3种模型生成的所有测试用例中事件处理函数的定义-引用对的覆盖情况,从图中可以看出,在执行相同的测试用例数时,基于EFG模型生成的测试用例覆盖的事件处理函数的定义-引用对数量最小,EHG模型次之,WEHG模型最大。这是由于建立EFG模型时未考虑代码层中不同事件之间同一变量的相互关系,从而导致生成的测试用例事件处理函数的定义-引用对覆盖不完全。而EHG模型虽然能够覆盖所有的事件处理函数的定义-引用对,但是没有根据事件处理函数中变量和定义-引用对对模型中节点和边设置权重值,导致一些定义-引用对在后部分测试用例中才能执行到。WEHG模型就解决了这个问题,提高了定义-引用对的覆盖效率。 图2 事件处理函数的定义-引用对覆盖数量的变化图 图3反映了执行基于3种模型生成的所有测试用例中发现缺陷的情况,从图中可以看出,基于EFG模型生成的测试用例有一个注入的缺陷没有发现,基于EHG模型和WEHG模型生成的测试用例发现了所有注入的缺陷,相比EHG模型,WEHG模型能够更快地发现GUI软件中的缺陷。 图3 发现缺陷的数目变化图 综上所述,本文提出的基于WEHG模型的GUI软件测试用例生成方法能够进一步提高GUI软件测试的效率,降低GUI测试的开销。且实验证明了通过对事件处理函数的事件所对应WEFG模型中节点设置权重,以及事件处理函数中的定义-引用对所对应节点之间的边设置依赖度,一方面能够更快地覆盖待测软件中的事件处理函数和事件处理函数中的定义-引用对,另一方面能更快地发现软件中的缺陷。 本文首先对EHG模型进行改进,通过对源代码的静态分析,对模型中的节点设置了权重,对边设置了依赖度,接着提出了基于WEHG模型生成抽象测试用例的算法,并结合EFG模型生成可执行测试用例。最后通过实验验证了本文提出的方法能有效提高覆盖事件处理函数和事件处理函数中定义-引用对的覆盖效率。在后续的研究中,将进一步提出对测试用例预判信息自动化生成的方法,并研究如何在能更多地发现缺陷的条件下进一步降低测试用例的数量。 参考文献: [1] Memon A M. A Comprehensive Framework for Testing Graphical User Interfaces[D]. University of Pittsburgh, 2001. [2] Dietrich C, Hoffmann M, Lohmann D. Cross-kernel control-flow-graph analysis for event-driven real-time systems[C]// Proceedings of the 16th ACM SIGPLAN/SIGBED Conference on Languages, Compilers and Tools for Embedded Systems. 2015: Article No. 6. [3] 陈军成,薛云志,赵琛. 一种基于事件处理函数的GUI测试方法[J]. 软件学报, 2013,24(12):2830-2842. [4] 陈军成,薛云志,陶秋铭,等. 基于事件处理函数的GUI测试用例集约简技术[J]. 软件学报, 2015,26(8):1871-1885. [5] Qian Siyou, Jiang Fan. An event interaction structure for GUI test case generation[C]// Proceedings of the 2nd IEEE International Conference on Computer Science and Information Technology. 2009:619-622. [6] Yuan Xun, Memon A M. Iterative execution-feedback model-directed GUI testing[J]. Information and Software Technology, 2010,52(5):559-575. [7] Zhao Lei, Gao Dongdong. GUI test case generation based on activity-flow graph[C]// Proceedings of the 7th IEEE International Conference on Software Engineering and Service Science. 2016:738-741. [8] 路斯瑶,胡飞. 基于事件流图的用户界面测试优化[J]. 测控技术, 2010,29(5):72-76. [9] Tovinkere V, Voss M. Flow graph designer: A tool for designing and analyzing Intel®threading building blocks flow graphs[C]// Proceedings of the 43rd International Conference on Parallel Processing Workshops. 2014:149-158. [10] 汪春. 基于事件流图的GUI自动化测试模型研究[D]. 武汉:华中科技大学, 2007. [11] 郭晶晶. 基于调用堆栈的GUI测试研究[D]. 上海:上海师范大学, 2010. [12] 江琴,刘琳岚,苏曦,等. 基于事件权重的GUI测试路径生成方法[J]. 计算机应用, 2009,29(5):1382-1384. [13] Brooks P A, Memon A M. Automated GUI testing guided by usage profiles[C]// Proceedings of the 22nd IEEE/ACM International Conference on Automated Software Engineering. 2007:333-342. [14] Suman, Chhillar R S. Generate optimized GUI test sequence using GA and fuzzy logic[J]. International Journal of Computer Applications, 2014,102(12):8-11. [15] 于冬琦,彭鑫,赵文耘. 使用抽象语法树和静态分析的克隆代码自动重构方法[J]. 小型微型计算机系统, 2009,30(9):1752-1760. [16] He Wei, Wang Yueke, Xing Kefei, et al. Error-rate estimation based on multi-signal flow graph model and accelerated radiation tests[J]. PLoS One, 2016,11(9), doi: 10.1371/journal.pone.0161378.2.4 结合EFG模型生成可执行测试用例算法
3 实验分析
3.1 实验环境
3.2 GUI测试用例评判准则
3.3 实验数据
4 结束语