写点什么

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:016490
用户头像

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

关注

评论

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

直播带货系统都有什么功能?如何搭建?

风行无疆

uni-app技术分享| 10分钟实现一个简易uniapp视频通话

anyRTC开发者

uni-app 音视频 WebRTC 实时通信 视频通话

9个问题,带你掌握流程控制语句中的java原理

华为云开发者联盟

Java 变量 finally 流程控制 语句

springboot从数据库中获取application配置

小鲍侃java

11月日更

Vue进阶(幺玖零):表单验证 trigger:‘blur‘ OR trigger:‘change‘ 区别

No Silver Bullet

Vue 表单校验 11月日更

Android Activity Deeplink启动来源获取源码分析

vivo互联网技术

android 源码解析 Activity

Apache APISIX 社区周报 | 2021 11.1-11.14

API7.ai 技术团队

云原生 API网关 社区周报 Apache APISIX

软件架构治理 之 如何识别和定位架构问题

码猿外

微服务 架构设计 软件架构治理

博文推荐|Pulsar 客户端编码最佳实践

Apache Pulsar

云原生 中间件 干货 Apache Pulsar 消息系统 客户端编码

【Flutter 专题】07 图解【登录】页面小优化

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 11月日更

一文详细分析公式树开源库

华为云开发者联盟

算法 数据 公式树 变异

令人不悦的–requests.exceptions.ProxyError

老表

Python Error 11月日更 ProxyError

如何在Java代码中使用SAP云平台CloudFoundry环境的环境变量

汪子熙

Java SAP CloudFoundry 11月日更

基于OneData的数据仓库方法论

大数据技术指南

11月日更

架构训练营模块七作业 - 设计消息队列存储消息数据的 MySQL 表

李焕之

数据分片的原则和经验

编程宝库

系统架构 数据分片 编程宝库

三大重磅报告,莅临GOPS全球运维大会#324龙智展位即可获取!

龙智—DevSecOps解决方案

运维 gops

【LeetCode】反转链表Java题解

Albert

算法 LeetCode 11月日更

【浪潮云说】直播间第十一期将于今晚19:30准时开播

云计算,

在 Spring Boot 中使用搜索引擎 Elasticsearch

码语者

Spring Boot Elastic Search

前端服务框架调研:Next.js、Nuxt.js、Nest.js、Fastify

智联大前端

node.js Vue 服务端 React

软硬一体的算法实践,阿里云如何以算法实现场景 “再创新”?

阿里云视频云

阿里云 算法 视频超分 视频云 异构计算

手把手带你玩转LiteOS Ping组件

华为云开发者联盟

协议 LiteOS ping 组件 数据包

Vue项目优化打包——前端加分项

CRMEB

来看看深度学习如何在文娱行业“落地”

博文视点Broadview

云小课 | DSC之数据水印,防止数据被盗用

华为云开发者联盟

版权保护 华为云 数据安全中心 数据水印 追踪溯源

往ABAP gateway system上和CloudFoundry 部署HTML5应用

汪子熙

log SAP CloudFoundry 11月日更

研究综述 | AI -自动化机器学习

索信达控股

机器学习 自动化机器学习 机器学习算法

实战 | 超详细的Kafka集群操作

五分钟学大数据

11月日更

dart系列之:dart类中的泛型

程序那些事

flutter dart 程序那些事 11月日更

Windows漏洞:MS08-067远程代码执行漏洞复现及深度防御

华为云开发者联盟

windows 漏洞 Windows漏洞 MS08-067 远程代码

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