自动化测试之PageObject设计模式

news2024/11/29 8:34:08

译文如下:

PageObject

当您针对网页编写测试时,您需要参考该网页中的元素以单击链接并确定显示的内容。但是,如果您编写直接操作 HTML 元素的测试用例,则您的测试将无法应对 UI 中的频繁修改。PageObject对应于一个HTML网页、页面组件或者一个特定的API接口,PageObject可以直接操作特定的业务场景如:注册、登录等,取代之前直接对HTML标签进行操作的流程。

pageObject

PageObject最基本的概念是它可以让软件客户端操作用户看到的或者用户可以操作的任何东西。它还应该提供易于操作的接口,并且对开发者来说隐藏内部逻辑。因此,要访问文本字段,您应该具有获取并返回字符串的访问器方法,复选框应使用布尔值,按钮应由面向操作的方法名称表示。

PageObject应该是封装用户感知到的界面、操作等机制。比较好的就是对外封装统一的接口定义,内部实现的改动不会影响到整体框架接口的改动。

尽管是将“Page”作为对象,但这些对象通常不应该为每个页面构建,而是为页面上的重要元素构建。因此,显示多个专辑的页面将有一个专辑列表的PageObject,其中包含多个专辑的PageObject。可能还有一个页眉的PageObject和一个页脚的PageObject。也就是说,复杂 UI 的某些层次结构只是为了构建 UI - 这种复合结构不应该由单一的PageObject表示。最好是对页面中会和用户有交互的结构建模。

同样,如果您导航到另一个页面,初始PageObject应该为新页面返回另一个PageObject。通常PageObject操作应该返回基本类型(字符串、日期)或其他PageObject。

对于PageObject是否应该包含断言本身,或者只是为测试脚本提供数据来执行断言,存在不同意见。在PageObject中包含断言的倡导者说,这有助于避免测试脚本中的断言重复,更容易提供更好的错误消息,并支持更多 TellDontAsk 风格的 API。无断言页面对象的拥护者说,包含断言将提供对PageObject的访问与断言逻辑的职责混合在一起,并导致PageObject膨胀。

我赞成在PageObject中没有断言。我认为您可以通过为常见断言提供断言库来避免重复,这也可以更容易地提供良好的诊断。

PageObject通常用于测试,但不应自己进行断言。他们的职责是提供对底层页面状态的访问。由测试客户端来执行断言逻辑。

我已经用 HTML 描述了这种模式,但同样的模式同样适用于任何 UI 技术。我已经看到这种模式被有效地用于隐藏 Java swing UI 的细节,而且我毫不怀疑它也被广泛用于几乎所有其他 UI 框架。

并发问题是PageObject可以封装的另一个主题。这可能涉及在异步操作中隐藏异步操作,而这些操作对用户来说并不显示为异步。它还可能涉及在 UI 框架中封装线程问题,您必须考虑在 UI 和工作线程之间如何分配

PageObject最常用于测试,但也可用于在应用程序之上提供脚本接口。通常最好将脚本界面放在 UI 下层,这通常不那么复杂且速度更快。然而,在有很多UI交互的应用程序,使用PageObject可能就不会成为最好的选择。 (但如果可以的话,请考虑移动该逻辑,这对于脚本编写和 UI 的长期健康都会更好。)

使用某种形式的 DomainSpecificLanguage 编写测试是很常见的,例如 Cucumber 或内部 DSL。如果您这样做,最好将测试 DSL 放在PageObject上,这样您就有一个解析器,可以将 DSL 语句转换为对PageObject的调用。

设计模式旨在将业务逻辑移出 UI 页面(例如表示模型、监督控制器和被动视图)这使得越来越少通过 UI 进行测试,并且减少了对PageObject的需求。

PageObject是封装的经典示例,它们对测试用例隐藏了操作UI的细节。在开发中试着去使用PageObject是很好的模式-问问自己“我怎样才能对软件的其余部分隐藏一些细节?” 与任何封装一样,这会产生两个好处。我已经强调过,通过将操作 UI 的逻辑限制在一个地方,您可以在那里修改它,而不会影响系统中的其他组件。一个相应的好处是它使客户端(测试)代码更容易理解,因为那里的逻辑是关于测试的意图,而不是被 UI 细节所干扰。

SeleniumHQ PageObject文章

原文链接:https://github.com/SeleniumHQ/selenium/wiki/PageObjects


译文如下:

PageObjects

页面对象

在您的 Web 应用程序的 UI 中,有一些与您的测试交互的区域。页面对象只是将这些建模为测试代码中的对象。这减少了重复代码的数量,意味着如果 UI 发生变化,则只需在一个地方应用修复。

实施说明

PageObjects 可以被认为是同时面向两个方向。面对测试的开发人员,它们代表特定页面提供的服务。远离开发人员,他们应该是唯一对页面(或页面的一部分)的 HTML 结构有深入了解的人最简单的方法是将页面对象上的方法视为提供“服务”页面提供而不是暴露页面的细节和机制。例如,想想任何基于 Web 的电子邮件系统的收件箱。它提供的服务通常包括撰写新电子邮件、选择阅读单个电子邮件以及在收件箱中列出电子邮件的主题行的能力。如何实现这些对测试来说无关紧要。

因为我们鼓励测试的开发人员尝试考虑他们正在交互的服务而不是实现,所以 PageObjects 应该很少公开底层 WebDriver 实例。为方便起见,PageObject 上的方法应返回其他 PageObject。这意味着我们可以通过我们的应用程序有效地模拟用户的旅程。这也意味着如果页面相互关联的方式发生变化(例如,当登录页面要求用户在他们第一次登录服务时更改密码时,以前没有这样做)只需更改适当的方法的签名将导致测试无法编译。换一种方式,

这种方法的一个后果是,可能需要对成功和不成功的登录进行建模(例如),或者根据应用程序的状态,单击可能会产生不同的结果。发生这种情况时,通常在 PageObject 上有多个方法:

public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}

复制

上面提供的代码显示了一个重要的点:测试,而不是 PageObjects,应该负责对页面的状态进行断言。例如:

public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}

复制

可以改写为:

public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}

复制

当然,与每个指南一样,也有例外,PageObjects 中常见的一个是在我们实例化 PageObject 时检查 WebDriver 是否在正确的页面上。这是在下面的示例中完成的。

最后,PageObject 不需要代表整个页面。它可能代表在站点或页面中多次出现的部分,例如站点导航。基本原则是您的测试套件中只有一个地方可以了解特定(页面的一部分)的 HTML 结构。

概括

  • 「公共方法代表页面提供的服务」
  • 「尽量不要暴露页面的内部结构」
  • 「一般不做断言」
  • 「方法返回其他 PageObjects」
  • 「不需要代表整个页面」
  • 「相同动作的不同结果被建模为不同的方法」

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/572502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5月26号软件资讯更新合集......

Windows Terminal 1.18 新功能预览:标签拖拽、上下文菜单... Windows Terminal 预览版已更新到 1.18 版本,带来多项实用内容,一起来看看这个版本的新东西: 标签撕裂(拖拽功能) Windows Terminal 已支持对…

安装Redis6

安装Redis 安装redis依赖 redis是基于C语言编写的,因此首选需要安装redis所需的gcc依赖 yum install -y gcc tcl 上传安装包并解压 我安装的是redis-6.2.6版本,并且放到了/usr/local/src目录下 - 进入/usr/local/src目录shellcd /usr/local/src解压 tar …

全球最受欢迎低代码平台排行榜出炉

低代码平台正在成为寻求快速有效地构建应用程序的企业的首选解决方案。这些平台减少了编码要求,使企业能够在降低成本的同时更快地完成应用程序开发项目。在本文中,将探索全球受欢迎的低代码平台排行榜。 该排名使用的标准包括易用性、成本效益、集成性、…

很后悔,才发现这个API管理神器

想必大家都注意到了,近半年国产API管理工具火了起来。这说明两个问题,第一,API管理的重要性被越来越多的开发者认识到了,研发团队对API管理的需求也越来越强了。第二,说明国产软件真是越来越厉害了,大家确实…

《微服务实战》 第十八章 Redis查看配置文件和数据类型

前言 本章节讲解如何查看、修改Redis配置,介绍Redis类型。 1、查看配置 config get 配置名称 2、修改配置项 config set 配置项名称 配置项值 2.1、配置项说明 配置项参数说明daemonizeno/yes默认为 no,表示 Redis 不是以守护进程的方式运行&#xff…

论C站如何获得铁粉?过来人给出几点建议

哈喽,我是bug菌,一名想走👣出大山改变命运的程序猿。周五啦,刚肝完需求的我,闲暇之时逛C站热榜,偶然刷到一条看到官方抛出的话题:"在C站如何获得铁粉?",我寻思…

操作系统第五章——输入输出管理(上)

提示:初入红尘,不知人间疾苦,蓦然回首,已是苦中之人,这杯中酒三分,这酒中悲七分。关关难过关关过,夜夜难熬夜夜熬,愿这人世间所有爱恨情仇皆溶于酒,且将这红尘做酒&#…

MP4如何让去水印?python带你实现~

前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 开发环境: 解释器版本: python 3.8 代码编辑器: pycharm 2021.2 模块使用: 内置模块(无需安装) os —> python系统编程的操作模块,提供了非常丰富的功能去处理文件和目录 sys —> 是与…

我是00后,我卷一点怎么了?

前段时间去面试了一个公司,成功拿到了offer,薪资也从12k涨到了18k,对于工作都还没两年的我来说,还是比较满意的,毕竟一些工作3、4年的可能还没我高。 我可能就是大家说的卷王,感觉自己年轻,所以…

手动创建django项目和python虚拟环境

在使用pycharm创建django项目的时候,报错如下: C:\Users\12051\AppData\Local\Temp\tmplkz609ucpycharm-management\setuptools-40.8.0\setup.py install Traceback (most recent call last):File "C:\Users\12051\AppData\Local\Temp\tmpqphl…

合并两个有序链表(java)

leetcode 21题:合并两个有序链表 题目描述解题思路:链表的其它题型。 题目描述 leetcode21题:合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入&…

IO多路转接

目录 一、select 1.1 select初识 1.2 select函数 1.3 scoket就绪条件 1.4 select基本工作流程 1.5 select服务器 1.6 select的优点 1.7 select的缺点 1.8 select的适用场景 二、poll 2.1 poll函数 2.2 poll服务器 2.3 poll的优点 && 缺点 三、epoll 3.1…

设备快线客户端软件V1.0用户手册

1.前言欢迎使用设备快线客户端软件产品。设备快线客户端软件简称DYClient,DYClient客户端是东用科技有限公司推出的一款用于远程维护的控制软件,主要为客户远程访问现场终端设备提供便捷的接入服务,并且通过DYClient客户端软件用户可以非常方便快捷的访问…

ChatGPT和软件测试实践与思考

前言 关于最近大火的ChatGPT相信各位也听过不同渠道听说过他的厉害,目前发展趋势比较火热,科技公司都有在考虑怎么使用ChatGPT进行提高研发效率以及办公效率,最近我所在的公司也有在要求大家使用ChatGPT进行改善工作效率,所以引发…

支持导入 Eolink 插件,别小看这个开源 API 管理工具了

Postcat 有多达 30 款支持数据迁移、主题、API 安全等方面的插件。 导入 Eolink 插件。 使用 导入功能有多个入口,你可以在 API 分组处点击加号导入 API: 也可以换种方式,在首页里导入Eolink 如果你日常会用到 api 管理工具的话&#xff0c…

【九章斩题录】C/C++:二维数组中的查找(JZ4)

精品题解 👉 《九章刷题录》 📜 目录: 「 法一 」暴力美学 「 法二 」十字分割法 「 法三 」逐行二分 JZ4 - 二维数组中的查找 📚 题目描述:在一个二维数组 array 中(每个一维数组的长度相同&#xff…

[时间同步] vscode chatGPT提供的程序打包封装成api解决方案怎么样

背景 在完成gnss时间同步程序大部分需求串口配置、串口数据中找出推荐定位信息RMC解析UTC时间以及UTC时间更新系统时间等功能后,有个需求比较特别,需要客户来操作。当车辆在地库场景待时间过久后重新回到地面,一直在自走的系统时间与又定位好…

Three.js--》探索Three.js:学习和就业的完整指南

目录 three.js的学习建议 WebGL前端工程师工作待遇相关问题 本篇文章主要给大家介绍一下如何学习Web3D可视化,具体说就是怎么学习WebGL、Three.js、3D建模等。 three.js的学习建议 在过去互联网是人联网的时代,开发人和人之间的联系的Web应用&#x…

MoveIt2中使用trac_ik

文章目录 1.下载trac_ik的源码2.安装 NLopt library3.编译源码4.使用 在ros1moveit1中,使用trac_ik是很简单的一件事情:【TRAC-IK Kinematics Solver】 但是在Ros2中,无论MoveIt2也好,还是trac_ik也好,都没有提供标准的…

如何编写快速高效的SQL查询(三)——高性能索引策略与样例

是时候开始讨论使用索引了!正确地创建和使用索引是实现高性能查询的基础,现在我们一起来看看如何真正地发挥这些索引的优势。 高效地选择和使用索引有很多种方式,其中有些是针对特殊案例的优化方法,有些则是针对特定行为的优化。…