发明内容
本发明所解决的技术问题是提供一种图形用户界面软件功能覆盖测试方法,解决了软件功能图自动生成问题。
技术方案如下:
一种图形用户界面软件功能覆盖测试方法,包括:
通过对被测软件进行分析,找出软件所有窗口之间调用关系、每一个窗口内部所包含的事件及其相互关系以及窗口之间的事件交互关系,并根据事件在测试过程中所起的作用对事件交互图进行简化;
对测试过程进行跟踪,捕获所述被测软件执行过程中所经过的窗口和事件,并根据捕获的所述测试用例的执行信息生成软件操作图;
对测试用例进行优化,根据测试用例测所覆盖的事件和事件路径等信息,剔除重复和冗余的测试用例;所述测试用例根据所述被测软件设计,在测试过程中,通过执行所述测试用例对所述被测软件进行测试;
将所述软件操作图与所述事件交互图进行比对,在所述事件交互图上标识出已覆盖的事件和事件交互,同时,给出测试覆盖统计结果;
判断是否满足覆盖标准,根据测试覆盖统计结果,判断是否满足设定的测试覆盖标准;若满足,则停止测试;否则,跟踪新的测试用例执行情况。
进一步:所述被测软件的信息分析是通过识别图形用户界面GUI软件中控件,在构建窗口调用关系图和窗口内事件关系图的基础上得到被测软件的事件交互图,并对事件交互图进行化简。
进一步:所述被测软件的信息分析的过程包括:
识别GUI软件中控件;
构建窗口调用关系图;
生成窗口内事件关系;
得到被测软件的事件交互图,内容包括控件的名称、属性和相互关系;
对事件交互图进行化简。
进一步:所述事件包括输入/输出性事件、系统交互事件、结构操作事件和无关联事件。
进一步:根据事件在测试过程中所起的作用对事件交互图进行简化时,根据对GUI软件窗口中的事件进行分类,去除不需要的事件之间的交互。
进一步:构造GUI窗口调用关系图时,对被测软件的窗口及控件进行捕获识别,按照窗口和控件的标题来识别被测软件的信息;如果出现反复使用的控件,使用控件的句柄来唯一标识,调用新的窗口后,使用窗口的句柄来标识窗口,并且记录窗口之间的调用关系,生成窗口调用关系图。
进一步:测试过程跟踪过程中,采用钩子技术捕获测试用例执行过程中所经过的窗口、事件和记录测试用例的执行过程,并根据捕获的测试用例执行信息,生成软件操作图。
进一步:对测试用例进行优化时在获取的软件操作图基础上进行,剔除重复和冗余的测试用例。
进一步:在判断是否满足覆盖标准之前还包括测试覆盖的统计与显示。
进一步:所述覆盖标准包括窗口覆盖准则、窗口内部事件覆盖准则、窗口内部事件交互覆盖准则、n长度事件路径覆盖准则或者输入空间覆盖准则;其中,所述窗口覆盖准则是指,当且仅当测试人员所设计的测试用例集T覆盖了GUI软件所包含的所有窗口,就称该测试用例集T是窗口覆盖充分的;所述窗口内部事件覆盖准则是指,当且仅当测试用例集T覆盖了窗口内部所有的事件,就称该测试用例集T是窗口内部事件覆盖充分的;所述窗口内部事件交互覆盖准则是指,当且仅当测试用例集T覆盖了GUI软件窗口内部所有事件交互,就称该测试用例集T是窗口内部事件交互覆盖充分的;所述n长度事件路径覆盖准则是指,当且仅当测试用例集T覆盖了GUI软件所包含的所有n长度事件路径,就称该测试用例集T是n长度事件路径覆盖充分的;所述输入空间覆盖准则是指,当且仅当测试用例集T覆盖了操作点序列中所有的输入空间特征值组合,就称该测试用例集对此操作点序列的输入空间是覆盖充分的。
本发明的技术效果如下:
1、解决了软件功能图自动生成问题。目前的软件功能图靠手工实现,工作量大,差错率高;
2、解决了事件交互图简化问题。本发明提出的简化方法符合软件测试实际,简化后对测试效果没有影响;
3、采用基于有向图的贪心算法对测试用例进行优化,并将其与测试过程有机结合。本发明提出的方法避免了普通贪心算法容易将两个不同路径的测试用例误合并问题;
4、采用增强的录制方法,能够识别屏幕上所显示的控件信息,记录信息的可读性好;
5、采用图形化方式,直观显示测试覆盖情况,并能够给出覆盖次数等信息,方便了测试人员使用。
具体实施方式
本发明主要解决软件功能图自动生成、测试过程跟踪、功能覆盖统计与显示、测试用例优化技术问题,使测试人员能够直观、准确掌握测试用例对软件功能的覆盖程度,为测试用例设计和测试充分性评估提供依据。
下面参考附图和优选实施例对本发明技术方案作详细描述。
如图1所示,是本发明的主流程图,GUI软件功能覆盖测试方法的步骤如下:
步骤S101:对被测软件进行分析。在测试过程中,通过执行测试用例对被测软件进行测试,测试用例的设计要根据被测软件的具体情况设计不同的测试用例。
通过对被测软件进行分析,找出软件所有窗口之间调用关系、每一个窗口内部所包含的事件及其相互关系和窗口之间事件交互关系,并根据事件在测试过程中所起的作用,得到事件交互信息(包括:指事件的名称、属性、可能的交互)并构建事件交互图,对事件交互图进行简化,剔除对测试没有影响或影响较少的事件交互。
被测软件信息分析主要通过识别GUI软件中控件,在构建窗口调用关系图、窗口内事件关系图的基础上,得到被测软件的事件交互图,并对事件交互图进行化简。
如图2所示,是软件信息分析流程图,步骤包括:
步骤201:识别GUI软件中控件;
GUI软件由控件组成,本发明使用如下结构来保存控件的五个属性值,分别是控件句柄、控件标题、控件类名、控件父窗口句柄、控件父窗口标题,在识别控件的过程中都需要调用相应的Win32 API底层函数。
控件属性结构如下:
控件句柄的获取方法如下:
控件标题获取方法如下:
控件类名获取方法如下:
控件父窗口句柄获取方法如下:
步骤202:构建窗口调用关系图;
GUI窗口调用关系图表示窗口之间的层级关系,为了构造GUI窗口调用关系图,首先需要对被测软件的窗口及控件进行捕获识别,然后按照窗口和控件的标题来识别被测软件的信息,如果出现反复使用的控件,需使用控件的句柄来唯一标识,调用新的窗口后,使用窗口的句柄来标识窗口,并且记录窗口之间的调用关系,生成窗口调用关系图。
本发明采用深度优先搜索算法,首先加载软件的主界面,而后从软件的主窗口开始,进行深度优先搜索,逐步打开所有的子窗口,生成窗口调用关系图,深度优先搜索算法中包括DFS()主控函数和DFS-Recursive()深度优先搜索过程函数,最终标识出每个顶点的前序和后序结点。
深度优先搜索算法结构如下:
步骤203:生成窗口内事件关系;
步骤204:得到被测软件的事件交互图,内容包括控件的名称、属性、相互关系;
步骤204:对事件交互图进行化简。
通过对被测GUI软件的信息分析而得到的事件交互数量庞大,如果不对事件交互规模进行简化,在实际测试过程中,难以覆盖所有这些事件交互。
(1)事件分类
为了有效简化事件交互数量,本发明中根据操作控件底层代码实现的不同,将事件分为四类:输入/出性事件、系统交互事件、结构操作事件和无关联事件。
输入/出性事件:输入/出性事件是指基本不需要人为编写代码的事件。这类事件通常由可视化的开发工具自动生成实现代码,其作用是为系统交互事件的执行提供数据的输入或者数据的输出,在一个比较典型的GUI软件中,文本输入框、显示框以及下拉菜单等控件所引发的事件均属于输入/出性事件,在GUI软件中此类控件占着很大比重,此类事件之间交互一般不会出现异常问题;
系统交互事件:系统交互事件是指实现系统功能但不引起GUI结构变化的事件,这部分事件一般需要人为编写代码,它的触发将用户的输入同系统的底层代码联系起来,实现了系统功能,但不引起GUI结构变化的事件;
结构操作事件:结构操作事件是指引发GUI软件结构变化的事件。这类事件引发了软件窗口的调用与返回,同一窗口内,这类事件只能作为终端事件,其它事件可以与其交互,其不参与和窗口内其它事件的交互;
无关联事件:无关联事件是指对事件交互没有影响的事件,这类事件完全独立,与其他事件没有任何交互依赖关系,它的执行与其他事件的执行与否和执行顺序没有任何的关系,它的执行也可能引发软件结构的变化。无关联事件的触发不需任何先决条件,运行结果也不对其他任何事件产生影响,这种事件一般完成相对独立的任务,与业务逻辑没有任何关联。测试人员可以把这类事件排除在事件交互的测试之外,只要是能够完成其独立的功能,就可以不进一步测试其与其它事件之间的交互。
(2)化简原则
通过上述介绍,根据对GUI软件窗口中的事件进行分类,去除不需要的事件之间的交互,就可以简化事件交互规模,如表1所示,√表示表格左侧事件与上面事件需要的交互,×表示表格左侧事件与上面事件不需要的交互,通过简化,从而可以大大减少可能的事件交互数量。
表1事件交互简化表
据表1所示,窗口内部事件交互有两大类:一、其它事件(输入/出性事件和系统交互事件)与系统交互事件的交互;二、其它事件(输入/出性事件和系统交互事件)与结构操作事件的交互。有了事件交互的统计后,增加它一个后续事件,就可以获得长度为3的事件序列的个数,同理可以获得任意长度事件序列的统计。
如图3所示,是MS记事本软件的替换窗口示意图。以MS记事本软件的替换窗口为例,简要介绍依据上述方法简化窗口内部事件交互的过程。窗口中包含7个可用控件,每个控件引发的事件都可以与其它控件引发的事件进行交互,加上自身与自身的交互,窗口内总的事件交互可以达到7×7=49个。根据上述事件分类的方法,其中输入/出性事件共3个,分别为“查找内容”文本框、“替换为”文本框、“区分大小写”;系统交互事件3个,分别为“查找下一个”按钮、“替换”按钮、“全部替换”按钮;无关事件1个,为“取消”按钮。
如图4所示,是简化后事件交互图。输入/出性事件需要和系统交互事件需要进行交互,系统交互事件之间需要进行交互,窗口内的事件交互数量为3×3+3×3=18个,比原来减少了31个,由此可见,去掉了无意义的事件交互后,大大减少了事件交互规模,在增大事件序列长度后,简化效果将会更加明显。
步骤S102:对测试过程进行跟踪。
捕获测试用例执行过程中所经过的窗口、事件,并根据捕获的测试用例执行信息,生成软件操作图。
测试过程跟踪主要用来记录测试用例的执行过程,如点击的按钮、输入的信息,通过跟踪,可以准确获取测试用例执行过程中所覆盖的界面元素。
测试过程跟踪过程中采用的主要技术是钩子技术和相关的Win32 API函数调用。钩子技术是Windows系统中一个重要的系统接口,是录制过程所需采用的重要技术,通过安装钩子程序就可以在应用程序或系统的消息进行处理之前对消息进行处理,它不仅可以拦截某一个线程的事件,还可以拦截整个Windows系统的事件,若需要拦截或监控用户的某项操作,在使用过程中需要安装和卸载钩子。
一、钩子操作
安装和卸载钩子需要以下API函数:
(1)安装钩子函数SetWindowsHookEx
其四个参数分别为钩子类型,钩子函数地址,钩子函数所在DLL的实例句柄,安装钩子后想监控的线程的ID号,返回参数为钩子句柄。
(2)卸载钩子:UnhookWindowsHookEx
参数只有一个,是要卸载的钩子句柄HHOOK hhk。
处理其他的控件的操作都是在钩子过程中实现,钩子函数过程_hookCallback=new HookProc(HookCallbackProcedure)在安装钩子函数时进行指定。。
二、控件处理过程
GUI软件中包含很多控件,这些控件的不同组合构成了风格各异的图形用户界面。控件不同,其识别和获取方式也不同,下面介绍GUI软件中各种控件的获取方法。
1、按钮
获取按钮控件文本的方法相对比较简单,关键的是判断按钮的类型,按钮控件包括三种类型:Button,CheckBox或RadioButton。其中主要用到的Win32 API函数有:GetWindowLong(hWnd,nIndex)。
如图5所示,是按钮控件获取流程图。利用GetWindowLong(hWnd,nIndex)函数判断按钮的具体类型,函数有两个参数:hWnd:窗口或控件的句柄;nIndex:指定要检索的基于0的偏移量,可以设置为GWL_EXSTYLE代表获得扩展窗口风格、GWL_STYLE代表获得窗口风格、GWL_HWNDPARENT代表如果父窗口存在,获得父窗口句柄。
2、文本框
获取文本框控件文本相对也比较简单,关键是对文本框的标签信息进行获取。
如图6所示,是文本框获取流程图。
文本框获取过程如下:
(1)编辑框编辑结束时查找文本框的标签坐标时,首先需要利用Win32API函数GetWindowRect(int hWnd,ref rt)找到文本框的左侧和底侧的坐标值,其中hWnd代表控件的句柄,rt代表一个结构,其功能是将句柄为hWnd的控件底侧、左侧、上侧、右侧的坐标拷贝到rt结构中,通过取rt结构的参数值即可。
(2)根据经验文本框的标签位置一般在其左侧或者上侧,首先从控件的左侧开始查询,按照x坐标递减的顺序,寻找控件类名是“LABEL”的控件,设置递减的长度,如果没有,再按照y坐标值递减的顺序进行查找,同样需要设置递减的长度,直到找到“LABEL”控件,将其标签属性标识文本框控件,对文本框进行抽象操作。
通过此方法,可以准确获得文本框所对应的屏幕上的标签,这也是本方法与录制方法最大的区别。
3、菜单项
菜单的结构是层次型构造,主菜单项在前端的接口中是可见的,下一层的菜单只有单击主菜单之后才会显示.
如图7所示,是菜单项获取流程图。
菜单项获取流程如下:
(1)当点击主菜单时,通过GetMenu(int hWin)函数返回菜单句柄,其中hWnd代表窗口的句柄;
(2)利用MenuItemFromPoint(int hWin,int hMenu,POINT pt)函数得到所点击主菜单选项在主菜单中的位置索引;
(3)调用GetMenuString(int hMenu,int topMenuIndex,int topMenuText,128,MF_BYPOSITION)函数获取主菜单的文本;
(4)此时子菜单打开,如果用户继续点击子菜单项,调用GetSubMenu(int hPreMenu,int topMenuIndex)函数获取子菜单项句柄;
(5)调用GetMenuString(int hSubMenu,int indexSub,int subMenuText,128,MF_BYCOMMAND)函数获取子菜单文本。
4、IP地址框
如图8所示,是IP地址框获取处理流程图。IP地址框的抽象处理关键是获取IP地址的内容及获取IP地址框的标签文本,获取IP地址内容简单易行,获取IP地址框的标签文本同获取文本框的标签文本方式相同。
5、ListBox列表框
如图9所示,是ListBox列表框获取处理流程图。ListBox列表框抽象处理关键是获取ListBox列表框的内容及获取ListBox列表框的标签文本,获取ListBox的标签文本同获取文本框标签文本相同,下面对获取ListBox列表框内容的处理进行具体描述:
(1)通过SendMessage(hpreLBWin,LB_GETCURSEL,0,0)函数获取所选取列表项的索引。
(2)通过SendMessage(hpreLBWin,LB_GETTEXT,combolIndex,wndListName)将所操作列表项的内容拷贝至自定义字符串中,然后进行抽象化处理。
6、CombolBox列表框
其处理方式同ListBox相同。
7、ListView控件
如图10所示,是ListView控件处理流程图。
步骤S1001:获取被测软件进程的ID,在该进程中开辟一块内存空间,控件相关信息存储在LVITEM结构中;
步骤S1002:向控件发送LVM_GETNEXTITEM消息,获取当前被选项的索引;
步骤S1003:向控件发送LVM_GETITEMTEXT消息,获取被选项内容字符数;
步骤S1004:从目标进程空间读出被选项的文本;
步骤S1005:打印对该控件操作语句。
8、未操作控件默认属性提取
对于设置参数属性的界面,测试过程中不一定对界面内所有的控件进行操作,这就需要在关闭界面时将其他没有操作过的控件的默认值取出。
如图11所示,是未操作控件默认属性提取流程图。
未操作控件默认属性提取流程如下:
(1)建立回调函数newCallBack(EnumChildWidgetCountCallBack),将回调过程EnumChildWidgetCountCallBack载入回调函数,具体操作在回调过程中进行处理。
(2)采用枚举函数EnumChildWindows(hwnd,myCallBack,0)将句柄为hwnd的窗口内的控件逐一枚举,在回调过程中进行处理。
三、软件操作图生成
在记录测试用例执行过程中,除了要获取所操作过的控件信息,还将控件之间的相互关系以文本形式保存在一个文件中,通过调用WinGraphVizAbout这个Dll中的画图函数接口showGraphvizFromFile(stringfilePath,string title),生成软件操作图。
如图12所示,是跟踪MS记事本软件中部分操作所得到的软件操作图。图中椭圆表示操作点,内容显示的是控件标题和测试人员的操作,有向边表示两个操作点之间执行的先后顺序,例如“文件LeftClick”指向“保存LeftClick”表示执行完左键单击“文件”操作后可以执行左键单击“保存”操作。
步骤S103:对测试用例进行优化。
根据测试用例所覆盖的事件和事件路径等信息,剔除重复和冗余的测试用例。测试用例优化在获取的软件操作图基础上进行,主要用来剔除重复和冗余的测试用例。测试用例优化技术在很多文献中都有登载,但这些技术大都是孤立的,没有与测试融为一体,商业化测试工具都没有包含这部分内容。本发明中将测试用例优化与功能覆盖测试融为一体,实现了测试与用例优化的无缝连接。
重复测试用例剔除:
所谓重复测试用例是指两个测试用例所经过的控件和控件顺序完全相同,显然,从覆盖的角度,这两个测试用例是重复的,任意剔除一个即可。
冗余测试用例剔除:
所谓冗余测试用例是指两个测试用例存在包含关系,即一个测试用例包含另外一个测试用例。为了得到个数最少的测试用例集,本发明中采用基于有向路径的贪心算法对测试用例进行优化。这个算法与普通贪心算法的最大区别是引入了有向图的概念,即,该算法处理的是有向图,而普通贪心算法处理的是孤立的点或边。算法主要包括以下几个部分:
(1)根据记录的每个测试用例所经过的路径,建立测试用例与路径之间的对应关系;
(2)选取最长路径对应的测试用例删除不需要的测试用例;
(3)根据路径之间的包含关系,剔除最长路径中子路径对应的测试用例;
(4)选取次长路径对应的测试用例,重复(3),直至所有的测试用例处理完毕。
步骤S104:测试覆盖的统计与显示。
将软件操作图与事件交互图进行比对,在事件交互图上标识出已覆盖的事件和事件交互,同时,给出测试覆盖统计结果。
测试覆盖统计与显示主要将测试用例的执行轨迹在软件功能图上标识出来,同时,统计出功能图中每一个点或边被覆盖的次数。
测试覆盖统计与显示主要通过比对软件功能图和软件操作图实现,步骤如下:
输入:软件功能图、软件操作图;
输出:测试覆盖的统计与显示图;
①读取软件功能图中的一个元素(点或边);
②采用深度优先或广度优先算法搜索软件功能图,直到找到功能图中对应的元素;
③将该元素标记为绿色(表示已被覆盖),同时将对应的计数器加1;
④重复①,直到处理完操作图中的所有元素
⑤将各个元素对应的计数器值标注于元素旁边,结束。
步骤S105:判断是否满足覆盖标准。
根据测试覆盖统计结果,判断是否满足测试覆盖标准,若满足,则停止测试,否则,跟踪新的测试用例执行情况。
本发明中提出了5种测试覆盖标准,分别是:
(1)窗口覆盖准则。当且仅当测试人员所设计的测试用例集T覆盖了GUI软件所包含的所有窗口,就称该测试用例集T是窗口覆盖充分的。
(2)窗口内部事件覆盖准则。当且仅当测试用例集T覆盖了GUI软件窗口内部所有的事件,就称该测试用例集T是窗口内部事件覆盖充分的。
(3)窗口内部事件交互覆盖准则。当且仅当测试用例集T覆盖了GUI软件窗口内部所有事件交互,就称该测试用例集T是窗口内部事件交互覆盖充分的。
(4)n长度事件路径覆盖准则。当且仅当测试用例集T覆盖了GUI软件所包含的所有n长度事件路径,就称该测试用例集T是n长度事件路径覆盖充分的。
(5)输入空间覆盖准则。当且仅当测试用例集T覆盖了操作点序列中所有的输入空间特征值组合,就称该测试用例集对此操作点序列的输入空间是覆盖充分的。
覆盖率计算
1)窗口覆盖率计算
设W’为进行测试执行过程中记录下所执行窗口的集合,||W’||为窗口集合W’中窗口的个数,则测试用例集T的窗口覆盖率为:
2)窗口内部事件覆盖率计算
设E′w是功能测试的过程中记录下的w窗口内包含的事件集合,PE′wP为w窗口内事件的个数,则测试用例集T的在窗口w内的事件覆盖率为:
此时将所有窗口的事件相加就会得到整个GUI软件的事件的个数,就进而得到GUI软件测试用例集T的事件覆盖率。
3)窗口内部事件交互覆盖率计算
设Ψ′w是功能测试过程中记录下的w窗口内包含事件交互集合,此集合只统计事件分类后认为对测试有意义的事件交互,PΨ′wP为Ψ′w集合中元素的个数,则测试用例集T在窗口w内的事件交互覆盖率为:
将所有窗口内部的事件交互及窗口调用树图边的数目相加,得到整个GUI软件的事件的个数,从而得到GUI软件的测试用例集T的事件交互覆盖率。
4)n长度事件路径覆盖率计算
设L′ne是功能测试过程中记录下的n长度事件序列路径的集合,PL′neP为此集合元素的个数,则测试用例集T的n长度事件序列路径覆盖率为: