发布新日志

  • (原创)使用类和xUnit模式实现GUI测试代码

    2010-09-21 12:53:57

     

    简述

    本文采用类对象的方式封装了项目的主要窗口的GUI对象, 大大方便了项目的主要窗口对象的调用和扩展。同时,也封装了GUI对象的检查点方法,使得测试代码逻辑进一步得到简化。另外,借鉴了xUnit 模式的设计方法, TestCaseTestSuit进行了分离, 方便了后续对测试代码的维护.

    动化测试的核心问题就是如何减少维护量,例如:我们应该使用对象库还是描述性编程?如果选择OR那么我们可以在每个ACTION中使用共享对象库或者本地对象库,那如果选择DP,可以有什么方式来实现吗?

    成本效益和可维护性是我们在做自动化测试中最为关注的,在此引出一个概念-GUI层扩展。这一概念经过的SOLMAR自动化专家组的分析和观察已被采纳,使用它就可以尽可能地提高代码重用性(通过使用面向对象的方法来提高效率,并分解出若干个抽象层且可维护性较高的自动化项目)。

    本文的思路是来源于QTP自动化测试的著名Web站点Advance QTPMeir Bar-Tal的一篇文章<<Implementing a GUI Layer with Classes>>. 这篇文章介绍了一种基于QTP的为为先进的自动化测试技术,本技术是由AdvancedQTP SOLMAR自动化测试专家组采纳的一组面向对象的实现技术中的一种。这种技术主要是把QTP描述性编程以及装载GUI对象的DICTIONARY对象通过业务驱动的方式来得到体现,最有价值的地方在于其对象识别的先发机制,可以有效的防止QTP在运行时识别对象出现卡住的现象,当对象出现不匹配时,能使测试顺利退出,并在报告中定位细节。有效的降低了测试的维护量并节省了自动化测试的时间。

     

    一.           GUI

    1.        封装GUI对象

    下面使用项目 CCConfirmDialogClass 窗口封装的GUI类做一个简单的介绍. CCConfirmDialogClass分为四个主要的部分:

    1)      对象类属性存取方法

    CCConfirmDialogClass内置一个Scripting.Dictionary 类型的m_htChildObjects成员, 它主要是用来存储GUI对象集合。

     

    2)      测试对象GUI界面控件对象层

    在类对象初始化中利用Scripting.Dictionary 容器对象,把GUI控件对象层上的对象封装起来,直接通过关键字在字典对象中定位对象,并针对对象进行操作来达成关键字字典对象驱动。

     

    3)      测试对象初始化检查公共函数

    类对象在运行时需要很多公共行为的函数, 比如IsInitialized函数判别GUI对象是否已经被正确的被加载,防止测试对象发生变化以后,与对象库中的对象无法匹配时测试流程会被中断导致超时错误信息,这样的情况会导致在自动化测试中浪费无谓的时间,因此使用工具函数IsContextLoaded函数检查GUI层中所有对象的是否已经存在并且把结果进行返回。其实这个函数的使用的时候并不是这么理想,有部分对象也在这个GUI层里但是并不是可见的,用这个方法只能检查始终是可见的对象,因此,稍后会讨论对于这种情况的解决方法。

     

    4)      业务逻辑函数

    CCConfirmDialog的主要业务逻辑行为就是对将要执行的行为回答”YES”或是“NO”。业务行为函数封装了采用关键字对测试对象访问的方法, 提供了方法调用的易用性和可维护性。

    代码示例如下图所示:

     


    2.        使用GUI对象

    GUI对象的实例采用了对象工厂方法实例化一个全局变量,供调用的其他GUI类或者测试逻辑中使用。

     

    GUI对象实例调用的形式如下图所示:

    CCClassFactory 方法有三个参数:

    ·        strClassType: 需要创建的GUI类名

    ·        objObject:对象实例变量

    ·        byval strObjec:对象实例变量名称

     

    CCClassFactory方法使用类单例模式(Singleton Pattern)实现,避免了GUI对象实例被多次引用时对象重复创建。

     

    3.        封装复杂GUI对象

    项目中有一些GUI对象较为复杂,比如一个GUI对象里包含多个子GUI对象,比如项目的 Destination Profile Configuration 窗口:


     

    因此,将Destination Profile ConfigurationGUI类分解为三个GUI子类:

    由此就可以分别将GUI对象和对于的业务逻辑封装在不同的子类中,而公共的GUI对象, 比如 Turn Edit On对象就封装在Destination Profile Configuration窗口GUI类中,这样很好的提升了代码的复用性。

    4.        简化测试执行流程

    通过GUI对象的封装,对测试执行流程进行了有效的简化,并且对代码的可读性也有了显著的改善。下面是一个Add Destination Profile 测试的例子。

     

    二.           检查点类

    既然通过对GUI对象的封装可以简化了测试执行的流程,能不能将这种方法推广到测试检查流程呢?检查点的流程和测试执行流程既有关联由于区别,通常情况下需要重复部分测试流程,但是也有不同的附加流程,比如在Patient Input的检查流程需要对已经录入的Patient记录进行检索,然后再查看录入的内容,因此使用对GUI对象的封装方法,也对检查点对象使用的GUI对象和检查逻辑进行封装。下面是一个检查 Add Destination Profile的例子:

    由此简化的测试执行流程和检查流程如下图所示:

     

    三.           使用xUnit Pattern 重构测试代码

    1.        断言(Assert

    断言是xUnit的最大特色之一,简化的调用方式使得嵌入在代码逻辑内的检查点既简洁又明确当前的检查类型和目标。封装一个Assert Class能够很好的简化测试流程,而且可以重构一些不明确的测试检查点。

    Assert Class 提供一些检查方法,比如assertEquals(检查两个变量相等),assertTrue(检查变量是否为真)等。

    虽然我们模仿了xUnit的断言,但是也不能一味的照搬,事实上与白盒测试不同的是基于GUI测试的检查点不仅仅需要检查结果,还需要通过检查控制测试流程是否进行下去,比如某个窗口不存在时就需要报错,然后中断测试流程执行下一个测试。xUnit的断言不是基于GUI的并不需要考虑这个问题。因此,必须对测试检查点进行分类实现。从检查以后产生的执行结果,我将检查点分为控制点(Control Point)和观察点(Observation Point)。观察点控制点只做值的检查,在检查成功或失败以后输出相应日志;控制点值的检查,在检查失败以后输出失败的日志,并且终止程序的执行。当然,这种划分不是绝对的,在有需要的情况下可以进一步扩展不同的检查点类型。

    由此,assertEqualsassertTrue 分类为两组检查点方法:assertCPEqualsassertCPTrueassertOPEquals assertOPTrue

    采用断言方法,测试的执行和检查可以进一步的被重构:

     

    在使用VBScript实现断言过程中,由于VBScript并不提供支持try-catch的异常抛出和捕捉处理机制。但是通过VBScript提供的on error resume next on error goto 0机制来实现断言机制。实现的大致过程如下:

    2.        SetUp TearDown

    使用SetUpTearDown方法可以将测试的前置条件(Prerequisite 后置条件(Restoration)进行有效的封装,重构以后的测试代码显的更加有条理和边界分明。比如,使用指定的用户登录系统是一个常见的前置条件。

    3.        TestSuite

    对于一组测试用例采用TestSuite的方式进行组织。与TestCaseSetUpTearDown方法类似,也可以采用同样的方法将更高层的公共前置条件和后置条件进行重构。下面是一个简单的例子:

     

     

     

    四.           结束语

    通过此次实践,我们找到了一种提高测试代码复用性的方法,虽然使用的效果还不是最为理想的,但是随着宿主语言对OO的支持的改进,这种思想和方面必将成为自动化测试发展的方向。

  • (原创) 基于Daily Build安装包的自动化测试流程在项目中的应用

    2010-09-21 12:45:13

    一.  前言

    Continuous Integration(持续集成)这个术语源自 XP(极限编程)的一个最佳实践,随着XP 社区在近几年的壮大,XP 的很多实践得到了广泛的推广,持续集成就是其中之一。事实上, 持续集成并不是一个全新的概念,在这个术语出现之前,Daily Build(日创建) ,他们的主要区别就在于实施的频率上,随着 XP 社区的大师级人物 Martin Fowler的一篇《Continuous Integration》正式为其正名,持续集成这个术语就越来越多地出现在原来Daily Build出现的位置。

    Paul M. DuvallCI实践的经典著作《Continuous Integration: Improving Software Quality and Reducing Risk》中对测试实践方面, 主要强调的是基于xUnit的自动化单元测试, 并没有对如何进行基于安装包的自动化测试流程实践进行描述。

    目前多数得对Daily Build的测试只能进行单元测试, 无法满足对安装包进行功能测试要求, 因此, 笔者在参与一个项目时, 为了解决实现对Daily Build 产生的安装包进行自动的安装部署之后的自动化测试的问题, 设计和实现了一个自动化测试的流程。

     

    二.  测试流程设计

    由于本项目是基于定制的Window Xpe的软件系统, 通过Ghost方式恢复初始安装系统是一个既简单又有效的手段。另外一方面, 为了能够实现自动运行功能测试用例, 就必须能够自动安装部署ATU和运行自动化测试用例所需的工具软件和环境变量。针对这两个关键问题我们设计了以下的主要步骤:

    1. Download Install package from remote server*
    2. Re-ghost test machine automatically
    3. Install CCPlatform. via QTP Script
    4. Build Test Environment for Running Test Script
    5. Run Test Script. Automatically
    6. Upload logs to remote server

    *: 目前公司有两个网络环境: 办公室网络和实验室网络. Daily Build Install Package 是放置在办公室网络里, Daily Build测试环境是在实验室网络里. 根据公司的IT Policy, 实验室网络仅能访问办公室网络指的服务器的特点目录.  因此, 在进行测试环境的部署前需要和公司IT和配置管理员联系获取可以访问的服务器地址和权限.

    详细步骤如下图所示:

    三.  关键技术实现

    1.      Re-Ghost Automatically

    为了确保测试环境的干净与测试结果的可靠性, 在每次运行自动化测试之前,对机器环境进行一次镜像恢复, 这样可以在最大程度上减少多次运行测试用例对环境的影响. 测试环境需要在一个稳定的可重复执行的restore process. 在恢复过程中,我们可以参考BaseImage的做法.将固定的公用程序打包到一个自定义的Ghost Image, 进行恢复.

    具体问题如下:

    a.       Ghost 运行环境

    目前系统是工作在Windows XPE 环境下, 一个稳定且可重复执行的过程的起点必然是在Windows XPE, 但是BaseImage, Ghost的运行环境是在Dos 6.0+ , 所以测试机必须同时具备两种环境. 一种是Windows XPE, 另一种是Dos 6.0+. 同时又要保证改两种环境是可启动状态.

    通过查阅MSDN, 以及参考Windows XPE 启动过程, 最终决定双环境启动流程如下:

     

    其中GRLDR, DOS6.0 是附加于boot.ini的第二启动项, 编辑 boot.ini 如下:


    [boot loader]

    timeout=5

    default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS

    [operating systems]

    multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Embedded" /fastdetect /NoExecute=OptIn /3GB /USERVA=2700

    C:\grldr="Daily Build Env"


    通过查询Ghost 11 说明文档, 在当前的Ghost环境中, Ghost能识别NTFS分区, 按照[硬盘编号]:[分区编号] 方式来识别NTFS分区, 例如: 1:1\CCBACKUP 表示第一个硬盘第一个分区下的CCBACKUP 目录. 因此确定GRLDR工作流为:

     

    实现过程如下:

     

                                                                              i.      创建并编辑GRLDR
    其中GRLDR中使用16进制编辑器修改为:

     

    find --set-root --ignore-floppies --ignore-cd /BD5NEW.img

    map --mem /BD5NEW.img (fd0)

    map --hook

    chainloader (fd0)+1

    rootnoverify (fd0)

     

                                                                            ii.      创建DOS启动镜像
    制作一张2.88MBDos6.0启动盘命名为BD5NEW.img:

                                                                          iii.      修改DOS启动配置文件运行指定命令
    修改Config.sys :

    [menu]

    menuitem=RESTORE, Start recover from an image.

    menuitem=BACKUP, Start backup to an image.

    menuitem=CUSTOM, Custom mode for Ghost.

    menudefault=RESTORE,3

    menucolor=7,0

     

    [RESTORE]

    device=himem.sys /testmem:off

     

    [BACKUP]

    device=himem.sys /testmem:off

     

    [CUSTOM]

    device=himem.sys /testmem:off

     

    [COMMON]

    files=10

    buffers=10

    dos=high,umb

    stacks=9,256

    devicehigh=ramdrive.sys /E 2048

    lastdrive=z

     

    修改Autoexec.bat
    A:\Smartdrv.exe /x

    IF "%config%"=="BACKUP" GOTO BACKUP

    IF "%config%"=="CUSTOM" GOTO CUSTOM

    A:\ghost.exe -clone,mode=pload,src=2:1\ccbackup\ccbackup.gho:1,dst=1:1 -sure –rb

                      在将上述文件放到C盘根目录下, 双环境就创建完毕.

     

    b.      运行环境之间的切换
     一个稳定可重复执行的过程同时也要求测试机可以对两种环境进行可控的切换. 包含从Windows XPE Dos6.0+, Dos6.0+ Windows XPE 的全自动可编程的逻辑过程.

     

    经过查询MSDN, 微软提供一个启动菜单编辑工具bootcfg.exe

     

    bootcfg.exe /Timeout 5

    bootcfg.exe /default /ID 2

    shutdown –r –t 1000

     

    这样当运行以上批处理命令, 计算机即可重启,并进入Dos环境, 为自动分区恢复的前提.


     

     

    2.      Auto-install Package

    由于需要进行功能性测试, 因此需要将安装包自动进行安装部署. 对于安装过程的控制, 采用QTP脚本自动运行和控制安装过程,具有可以对不同版本和形式的安装包进行可监控和参数配置处理.

    项目是一个比较复杂的安装过程, 在安装过程中需要调用很多不同的第三方安装程序或者其他系统组件安装包, 比如JRE, MSVC++ Redistribution, Eclipse, MIM等等. 需要控制安装过程就需要对不同的安装界面进行识别和控制,具体的问题如下:

    ·         Processing Dialog

    在使用QTPCC的安装过程控制时, 经常遇到一些如下图所示的Processing Wait Window 窗口. 这类窗口控制的难点是无法准确的预计这个窗口什么时候关闭, 然后进行下一步处理.

     

     

    笔者通过对使用UI 对象的WaitProperty方法扩展了Window的方法WaitPropertyUntilNotExistWaitPropertyUntilExist"实现了对Processing Wait Window的准确处理,  调用的示例代码:

    其中, WaitPropertyUntilNotExist(“visible”, “True”)代表的含义是当对象的visual属性值为True时开始等待直到它不存在.

    其中, WaitPropertyUntilExist(“visible”, “True”)代表的含义是一直等待到对象的visual属性值为True.

     

     

    实现的VBScript的代码如下:

     

     

    ·         Operate Command Line Window

    由于项目安装过程中调用了很多的脚步文件, 因此经常会遇到处理Command Window的情况, 比如, 按装Eclipse的组件的时候, 需要在这个窗口出现的时候对窗口做一个Press Key的动作. 处理这样的窗口主要的问题由两个: 1). 如何识别Command Line Window窗口需要输入动作; 2). 如何对Command Line Window进行输入动作.

     

    解决以上的问题主要的方法就是通过UI对象的GetVisibleText方法获取特征文本,然后调用 UI对象的Type方法进行输入动作, 调用的示例代码:

     

    实现的VBScript的代码如下:

     

     

    3.      Log Mechanism

     

    由于在整个自动化测试流程是分为几个不同的阶段有不同的程序控制调用完成的, 任何一个部分都有可能出现问题, 因此为了方便的追溯和解决问题, 每执行的部分都提供了统一格式的Log信息. 在执行完毕, <SPAN lang=ZH-CN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'T

  • Open2Test Framework

    2010-07-29 14:39:23

    而然在网络上搜索到了Open2Test Framework, 这个是基于KeyWord的开源测试框架, 支持很多的测试工具:QTP,TP,SkillTest,Selenium...

    详细的资料参考这个网站 http://www.open2test.org/index.html 吧!

    我所要说的是这个框架的问题:

    1. 没有很好的学习的例子,上手比较慢

    2. 代码中有很多错误

    3. 较难调试

    4. 编写测试也比较困难

    这是目前发现的比较大问题的问题, 前两个问题, 我在熟悉过程中把他们逐步解决,然后共享出来给大家, 后面两个问题只有开发一个好的工具能够对他们进行解决.

Open Toolbar