客户端稳定性测试
稳定性测试是在保证功能完整正确的前提下,必不可少的一项测试内容,通过对软件稳定性的测试可以观察在一个运行周期内、一定的压力条件下,软件的出错机率、性能劣化趋势等。进而大大减少软件上线后的崩溃卡死等现象,为软件的逐步优化提供方向及验证。
无论是服务器端还是客户端,对稳定性的测试无非是就是测试系统的长期稳定运行能力。在系统运行过程中,对系统施压,观察系统的各种性能指标,以及服务器的指标。不同于服务器端的稳定性测试的是,客户端软件是运行在单机环境下,所以不存在并发用户数的概念,取而代之的是一些多进程长时间的操作,以及各种复杂的并发场景的组合。一款客户端软件,它的稳定性测试需求基本包括:
1、长时间运行及各种操作下,软件的稳定性以及各种性能指标的劣化趋势。
2、多进程或多线程运行时的稳定性。
3、不同操作系统,在不同宿主软件下运行的稳定性。
稳定性测试实施
整个稳定性测试的包括三大部分:
1、场景的设计及实现
2、稳定性测试的执行
3、最后结果的校验
场景设计
测试场景一般是指模拟平常的压力,以及模拟实际中用户的日常操作,如果包含数据库,那么数据库要存有一定的数据。一般来说客户端产品的稳定性测试包括:
自动化脚本
自动化测试是稳定性测试的基础,对于使用标准控件的客户端软件来说,可以使用市面上较为通用的自动化及性能测试软件QTP或LoadRunner,这些软件对标准控件支持较好,可以很方便快速的搭建起自动化测试的框架,为稳定性测试提供基础。
但由于目前客户端软件的界面开发为了更加快速,同时融入业界前沿的皮肤技术,为用户创建更加高效,专业的界面,大多数都采用了DirectUI的技术,这种方式是直接在父窗口上绘图。即子窗口不以窗口句柄的形式创建,只是逻辑上的窗口,绘制在父窗口之上。对于这种非标准控件如果使用QTP等自动化测试工具就会显得力不从心了。
基于以上面临的问题,一种“开后门”的方法引起了我们的注意,“后门”是指RD在程序中专门为了某些目的开设的访问通道,通过这些隐秘不为人知的数据访问通道,可以实现特殊的产品功能。对于自动化来说,我们可以通过这种方式将程序的一些界面信息暴露,当然也不局限于UI的信息,我们也可以将任意测试程序需要的信息通过后门的方式暴露给我们自己的测试程序即可以实现自动化相关的需求。
这个想法在后期的实践中逐步优化,最终形成了一套基于Proxy架构的自动化解决方案。当被测程序启动时,加载Proxy,并将皮肤引擎的指针(全局变量)传入Proxy中,自动化脚本通过与Proxy通信,实时获取UI的各种信息该框架包含两大部分:
1、一部分是以Pywinauto(Pywinauto是一些用于自动化测试Windows标准图形界面的模块的集合。它可以允许你很容易的发送鼠标、键盘动作给Windows的对话框和控件)为操作基础,pyunittest为case组织框架的python脚本部分,这部分包含了关键字的封装,case的实现。
2、另一部分是植入到被测程序内部的Proxy,当被测程序启动时,加载Proxy,并将皮肤引擎的指针(单例)传入Proxy中,自动化脚本通过与Proxy通信,实时获取UI的各种信息,从而达到自动化的操作以及验证的目的。
整个自动化框架图如下:
执行
稳定性测试不同于功能测试的自动化,它属于一种概率性的测试,需要长期运行过后才能得出最后的测试结论,即使稳定性测试通过,也不能保证系统实际运行的时候不出问题。所以要尽可能的提高测试的可靠性,我们可以通过多次测试,延长测试时间,增大测试压力来提高测试的可靠性。
当稳定性场景存在多组时,为了保证运行的及时性与可靠性,同时也为了满足测试环境的丰富性,稳定性测试的执行需要多台机器才行。如果条件允许,可以使用不同环境及配置的物理机进行测试,也可以使用虚拟机,构建丰富的环境中心来满足稳定性测试的需求。
当存在多个运行环境和多组case时,为了保证测试场景组合的多样性,各组case要阶段性的循环在每个运行环境中执行,因此需要一个清晰明确的执行计划和记录:
结果
从稳定性的测试目的中可以得出在对稳定性结果的判断需要从以下几个方面进行:
1、判断是否崩溃
a) 对于能够被崩溃上报进程捕获的的崩溃比较好办,可以通过判断是否有崩溃上报进程来进行判断。
b) 在测试机上安装任意的debugger工具(例如windbg)就可以检测各种类型的崩溃情况(只要有崩溃就会触发debugger的调用,检测是否出现debugger进程就ok)
c) 对于那种运行在宿主程序中的插件,单独插件的崩溃有时不会导致宿主程序的整个崩溃,所以对插件崩溃的检测需要记录运行正常时的pid或tid,发现其消失就判断为崩溃,因为插件运行在宿主程序中不是一个进程就是一个线程。
2、判断是否假死
a) 对于单进程程序,只要主窗口发消息即可,找对主窗口是关键,通过枚举某个进程的全部窗口句柄,找parent为null,visible 为true,不是托盘程序的那个窗口句柄。
b) 强制主窗口重绘(这个重绘方式各产品可能不一样,有的发消息就可以,有的需要移动位置),然后截图,白色的就是假死(判断白色的已有现成的代码)
3、判断是否存在性能劣化的趋势
a) 这点也属于性能测试中资源占用情况的测试,可以再稳定性测试的同时使用性能检测工具进行检测。
待改进点
1、自动化判断,定位异常信息。目前一些偶现的卡死和崩溃无法捕获到堆栈信息,对定位意义的不大,需要在崩溃或卡死时保留住现场,不能连续的执行后续的case。
2、操作步骤及数据选取的随机性。可以考虑引入Fuzzy以及解析用户日志的方式增加操作步骤及测试数据选取的随机性。
3、测试case在各个执行环境中循环切换的自动化。目前这种循环还是靠手工保证,后续可以考虑从在每台测试机器上动态调用测试脚本,代替手工的切换及运行。
4、测试脚本的稳定性:稳定性的测试不仅是对被测程序稳定性的验证,同时也考验我们自动化测试脚本运行的是否稳定,而且在长时间的运行过程中可能会出现各种阻碍脚本运行的但却是正常的情况,所以需要增加各种判断和轮询的机制,另外为了保证场景的多样性都需要我们的脚本更加通用和周密,一不小心,被测程序还没挂呢,我们自己先停了……对于脚本的稳定性一直在测试的过程中不断完善,积累经验。
(作者:gjhui)