写点什么

GUI 功能测试自动化模式

  • 2013-10-21
  • 本文字数:4248 字

    阅读完需:约 14 分钟

对于某个特定程序,为其开发自动化功能测试解决方案的过程,与创建该程序的过程,二者相较并没有很悬殊的差别。自动化测试是一个非常年轻的领域,它正在不断经历大量的进步、提升和标准化进程。在这个领域中,涌现了许多与“被测系统”(SUT,System Under Test)互动的新工具。

现在,软件开发方面有大量可供选择的方法论和途径,例如:面向对象编程、函数式编程、领域驱动设计测试驱动设计行为驱动设计等等。它们拥有明确的声明性概念和理论,并简化了对初始系统架构的定义过程、对系统的理解以及开发者之间的知识交换等方面的工作。

本文将主要针对GUI(图形用户界面)应用的测试自动化进行讨论——从自动化开发人员的角度看,在这种情况下被测系统(SUT)表现为一个黑箱(被测系统,是指一个正在测试是否能够正确操作的系统。对于桌面应用来说,它就是应用本身,而对浏览器系统来说——则代表了网站/Web 项目等含义)。在公司的遗留系统占很高比例的环境里,或是在新开发的系统没有考虑可检测质量属性时,这一现象非常常见。

对最佳实践的准备和定义,是开发自动化的测试的关键部分。下图展示了被测系统和测试者之间的传统交互:

测试者与SUT 之间的交互

位于该系统中心的,是一个扮演测试者角色的人类个体。测试者使用手动交互和应用的视觉化分析,以及特定的SUT 非可视化界面访问工具,将测试用例中所描绘的场景进行复制。如果失败或是遇到系统意外行为,测试者便将错误行为的有关信息输入到默认的追踪系统中。

自动化测试的主要目的,是消除(或者至少最小化)人类与SUT 之间的交互。在持续交付产品开发周期中,这是非常常见的问题。一份文献来源的研究表明,现在自动化测试系统的数量非常多。商业产品一般会公布一系列详细的要求和推荐,特别适用于其产品。但是这些厂家往往不会公布适合与任何自动工具一起使用的一系列工具诊断实践。

此外,这些自动工具软件提供商往往还会运用营销手段,基于小量功能测试来描绘其系统的优势。但是随着自动化测试数量的增长,维护现有测试将成为系统工作流程中最昂贵的部分。

自动化测试框架旨在帮忙解决这些问题。他们定义了基本的系统可复用组件,公布了最佳实践和统一自动方法——为了正确地开发自动化测试框架,我们需要得到独立最佳实践的指导。

自动化功能测试的模式

让我们检查以下Web 应用程序自动化方面的问题(图1),这是一个自动化解决方案装置的例子。该应用包含了一幅登录页面,而每项测试都必须经过该页面,才能进行更进一步的测试。

图1:示例——拥有最少页面和功能集的简单Web 应用

分类体系(图2)为我们带来了全部功能测试模式的整体视角,本文稍后会对各个模式展开描述。

图2:自动化功能测试模式的分类

测试实现的模式

记录

通过自动化测试工具来执行此模式的测试实现。该工具记录并回放手工测试者的操作。某种程度上,考虑到昂贵的维护成本,这种方式被认为是一个糟糕的实践。

脚本化

由程序员使用自动化工具的API 来执行测试实现(例如Selenium WebDriver API)。

实现基础模板(测试模板)

该模式将实现基础测试模板类。要实现各种测试的变体,可以通过继承和扩展模板类的功能来创建。

数据驱动实现

通过测试用例来定义一个基础测试的实现。可以通过一系列不同的输入数据组合,来创建各种测试的变体。

在大部分单元测试框架中都实现了这一方法,例如:MSTest 以DataContext(键值集合)的方式,提供对测试内部的属性的访问权限。于是,相同的测试方法主体会运行很多次,但DataContext 属性所提供的数据各不相同。

关键字驱动实现

这一测试实现借助了关键字(例如:点击、回车)。测试实现通过特殊的IDE 完成,这类IDE 可以钩挂到应用的UI 上。

目前已有数款软件工具,支持借助关键字来实现测试。测试的步骤,以关键字、屏幕上的控制名和输入参数的结合的形式出现。HP QTP 和MonkeyTalk 是这类IDE 中的典型例子

模型驱动实现

对任何应用来说,在特定的时刻接受特定的输入,都只会有一个特定的状态。根据这样的定义,我们可以将软件程序描绘为有限状态机(有限自动机)。考虑到这一事实,以及状态可用性和转换模型(例如图1),我们可以定义一套特定的页面间转换(工作流)的集合,它将能够覆盖程序的大部分功能。

架构模式

多层的测试解决方案

该模式从逻辑维度将正在测试的系统划分为独立的逻辑层级。

将软件系统以架构性方式分为独立的层级是一个广为流传的实践。第一层封装了表述逻辑,第二层则是业务逻辑层,而第三层负责数据存储。使用这一范式,有助于降低应用维护成本,因为更换每层内部的组件对其他层级的影响将被最小化。而同样的方法也可以运用到测试系统中。

测试代码同样可以分为三层:用来向SUT 提供访问的UI 自动化工具界面层、功能逻辑层和测试用例层。每一层都肩负特定的责任,而它们都在追求共同的目标——降低测试维护成本,提升创建新测试的便利性。

图 3: 架构性原型——测试系统的多层架构

元框架

该模式定义了一组基础的独立工具类。对任何自动化工具来说,它们都是通用的,而且可以在不同自动化项目之间复用。

当需要在一个组织机构中测试不同的项目,而且企业标准要求测试结果采用统一的界面时,或许就需要这样的解决方案。此外,元框架改进了项目间代码复用的度量标准,因为它可能会包含有用的工具方法。有关功能和测试对象的基础类,简化了项目之间知识的转移。元框架展现在图3 的右侧。

功能组合模式

功能方法

针对特定于应用的业务功能,从其UI 实现、API 或其他层面进行了抽象。

用于自动化测试的许多工具,都支持创建被称之为“场景记录”的功能。当一位测试开发者针对特定应用执行特定操作时,这些工具将自动创建一份测试脚本。它可以在稍后进行回放,并检查在程序发生变化后,该脚本是否得到了正确的执行。

例子:改变登录界面的外观,将要求在全部预计的测试场景中的对应部分都进行变更。如果我们将登录方法提取为Application.Login(username,password),并在全部测试中使用这一方法,那么当登陆页面发生任何变更的时候,我们将只需要修改仅仅这一个功能方法,随后变更就会被自动分发到所有使用该方法的测试中。

图4:测试脚本与(a) 缺乏功能方法的过渡层的用户界面之间的交互;(b) 带有功能方法层的用户界面。当应用发生变更时,阴影部分对象将会被改变。

页面对象

这一模式将某个页面的功能方法组合在一起。

由于图1 中展现的用于应用的功能方法数量不多,因此它们可以移入一个单独的类。但是为了提升代码可维护性,此模式建议依据这些方法所代表页面,对其进行分组。例如,这些对应关系可以包括:页面:PageLogin——方法:Login();页面PageHome——方法:Logout()、CreateUser()。

功能库

它将某个特定应用的功能对象或(和)功能方法分组打包,成为一个适合复用的模块。

SUT 的启动和拆卸对象(SUT 运行者)

该模式支持被测系统的初始启动,即它的初始化。在此之后,测试对象释放与该系统相关的资源。

在功能方法之中,我们可以区分出与功能测试无关的方法集合:例如启动某个 Web 浏览器,并访问 SUT 的登录页面。而在测试之后,Web 浏览器应该被关闭。SUT 运行者负责以上这些通用活动。

对象源(对象之母、对象精灵、对象工程)

该模式按测试执行所要求的形式,创建并初始化的对象。

运输者(导航器)

根据测试要求,它将被测试系统中的导航控制集中在一起。

该对象封装了与被测试系统内部的导航实现有关的完整逻辑。因此业务逻辑的问题不会影响系统内的导航。

对于图 1 所描述的情况,我们将拥有一个 Transporter 类(运输者),它拥有以下方法:NavigateToLogin()、NavigateToHomePage() 和 NavigateToCreateuser() 等等。或者,每个独立的页面(page)对象或许都会拥有自己的运输(transport)方法。在这种情况下,这些方法就作为该对象自身的运输者

复合页面对象

该模式将复用的页面(page)对象聚合在一个外部对象中。

这一模式支持用更加“面向对象”的方式来组织页面对象——把可以在不同页面上复用的子对象分离,并将其包含到父对象中。

图 5:通过在主页和创建用户页面对象中聚集,来使用导航页面(Navigation Page)对象

扩展的页面对象

该模式通过继承来扩展基础的页面对象,成为复合页面对象的替代选择。

过程模式

给定条件 / 时机 / 结果

此模式将测试执行过程分为三个阶段:

  • 给定条件(定义先决条件)
  • 时机(设定与上下文协同工作的特定操作)
  • 结果(检查结果)

四阶段测试

此模式将测试执行过程分为四个阶段:

  • 定义先决条件
  • 调用业务功能
  • Checking results;
  • 拆卸系统

流测试

该模式支持在一个测试内执行业务操作并进行检查。两项内容可以交替进行,直到实现测试的最终目标。

多次失败

该模式定义了一套机制,能够在非致命错误出现之后继续进行测试。

测试依赖模式

独立测试

该模式令被测试的系统回到测试前的状态。

链式测试

在该模式中,初步测试树立起了测试需要跟踪的 SUT 状态。

测试分组模式

每个测试类封装一个测试方法

在该模式下,每个独立的测试方法,都封装在一个独立的测试类中。

测试类中的分组测试方法

在该模式下,多个测试方法被放置于一个独立的测试类中。

总结

测试解决方案的设计背后的驱动力,是对特定测试实现模式的选择。它扮演了未来所有测试解决方案开发的起点,将在可读性、可维护性和其他诸多特性方面产生影响。而且它也设置了这些实验,使其在能够产生帮助的时候更好地复用项目之间的资源,并减少新项目自动启动的时间。

这篇文章抛出了有关如何参考设计模式,来构建测试解决方案的想法。

参考文献

  1. “设计模式:可复用面向对象软件的基础”,作者:Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides,Addison-Wesley Professional 于 1994 年出版;
  2. “xUnit 测试模式:测试码重构”,作者:Gerard Meszaros,Addison-Wesley 于 2007 年出版;
  3. 论文 Design Patterns for Customer Testing,作者:Misha Rybalov,一位以质量为中心的开发者;
  4. 论文 Meta-Framework: A New Pattern for Test Automation,作者:来自 Symantec 公司 Security 2.0 团队的 Ryan Gerard 和 Amit Mathur
  5. Selenium–Wiki__ 页面

关于作者

Oleksandr Reminnyi SoftServe 股份有限公司的软件架构师,SoftServe 是一家全球领先的软件开发、测试和技术咨询服务提供商。Oleksandr 负责为新客户和已有客户建立自动化项目和流程。他相信自动化的成功与否,完全取决于已经建立起来的流程,以及是否设定正确的目标。Oleksandr 目前正在致力于完成自动化方面的博士研究。他的联系方式为 orem@softserveinc.com

**** 查看英文原文: Functional GUI Testing Automation Patterns

2013-10-21 08:016536
用户头像

发布了 256 篇内容, 共 73.5 次阅读, 收获喜欢 10 次。

关注

评论

发布
暂无评论
发现更多内容

惨遭泄密!阿里P8大佬的架构笔记外泄:微服务分布式架构实践手册

Java 编程 架构 面试 架构师

Redis

ltc

redis

解读区块链技术在中小企业中的4种常见用例

CECBC

如何利用 Apache APISX 提升 Nginx 的可观测性

API7.ai 技术团队

nginx 开源 网关 APISIX

高可用架构(上)

编号94530

微服务 数据库设计 架构设计 高可用架构 高可用集群

【前端 · 面试 】HTTP 总结(十)—— HTTP 缓存应用

编程三昧

面试 8月日更 HTTP缓存

什么是通证经济?它和区块链又有什么关系呢?

CECBC

AlertManager 告警发送频率探究

greatersecurity

Flink的DataStream API(v1_7)(五)

Databri_AI

flink 并行 函数

SpringSecurity+JWT实现前后端分离的使用

4ye

Java 后端 springsecurity JWT 8月日更

苹果手机请求程序报network error错误

石云升

bug 8月日更 兼容问题

oVirt Exporter 监控

耳东@Erdong

Prometheus exporter 8月日更 oVirt

创建型设计模式之单例模式

卢卡多多

设计模式 单例模式 8月日更

保险污名化?区块链赋予保险的「四个机会」

CECBC

链路压测中的支路问题初探

FunTester

性能测试 测试框架 压力测试 全链路压测 测试开发

字节大牛把算法常见面试:哈希、链表、队列、递归全部总结出来了

Java 程序员 面试 算法 计算机

从 async 和 await 函数返回值说原理

devpoint

Promise Async 8月日更

Tensorflow随笔(三)

毛显新

人工智能 神经网络 深度学习 tensorflow

人类高质量程序员如何过七夕?

InfoQ写作社区官方

话题讨论

书山有路,AI为径:科大讯飞如何在智能教育硬件赛场突出重围?

脑极体

想不到阿里内部的神级项目和JDK源码阅读指南竟惨遭GitHub开源

Java 架构 面试 程序人生 计算机

滚雪球学 Python 第三轮,Python Web 之 Django 的世界

梦想橡皮擦

8月日更

我要上首页!自荐好文,官方百万流量扶持

InfoQ写作社区官方

9月日更 11月日更 12月日更 热门活动 10月月更

【SpringCloud技术专题】「原生态Fegin」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(中)

洛神灬殇

SpringCloud OpenFegin Fegin 8月日更

合并两个有序数组

Memorys

Java 面试 算法

react脚手架create-react-app学习笔记

Tao

React

套接字

一个大红包

8月日更

前端之数据结构(七)堆

Augus

数据结构 8月日更

迈入 8K 时代,AI 驱动超高清 “视” 界到来

阿里云CloudImagine

阿里云 高清视频 视频处理 视频制作 视频云

【设计模式】享元模式

Andy阿辉

C# 后端 设计模式 8月日更

JNI不正确的信号处理导致 JVM 崩溃问题分析

毕昇JDK社区

GUI功能测试自动化模式_软件工程_Oleksandr Reminnyi_InfoQ精选文章