GUI自动化测试进阶:页面对象模式

本文介绍的是页面对象设计模式及其常见的滥用继承的错误。

本文和语言无关,但作者主要使用python和java。本文假设读者已经具有了一定的python或java基础,知道类和方法是什么。

如果完全没有这方面的基础,请看我的《测试人员如何学Python》。

页面对象模式主要用于基于图形界面的自动化测试,如果没有这方面的基础,请看我的《Selenium的学习》。当然,本文也适用于移动端的图形界面自动化。


一、页面对象模式简介

在使用页面对象模式之前的脚本,可能是这样的:

这样的脚本的问题就是,我如果创建了100个脚本,每个脚本里都有用户登录。

当有一天用户登录的页面改了:以前id叫username的文本框改成了id叫user。

我就不得不更新这全部的100个脚本。而网站往往隔三差五就要改版。这一百个脚本的维护工作很快就会把测试人员压垮。

于是,我们引入了页面对象,

所谓页面对象,即是页面元素加页面服务:

在引入页面对象之后,代码的组织是这样的:

 

 具体到页面类内部,是这样的:

于是你看到的页面类这样的,此处我使用伪代码来描述,请自行转化成自己使用的语言。这里我是假设有一个在线电影网站(我的第一个自动化框架就是针对一个在线电影网站),提供用户注册功能。

 

而脚本则是这样的

 

这里脚本的脚本本身只有一行代码:

从注册页开始,先注册新用户,然后返回首页,然后搜索一部电影“雷神”,最后购买。注意,这仅仅是一个例子,我以方法链的形式来写了这个脚本,而且没有加断言。实际工作中,不建议你以方法链的方式来写脚本,实际上的脚本可能是写成这样的:

 

看完这个解释,大家是否对页面对象有了一定的理解了呢?

那么请尝试一下,找一个网站,给他的某个页面建立一个XXXPage类,然后封装一些这个页面的元素和服务吧。

二、面向对象不仅仅是继承

提到面向对象,大家可能在脑海里马上联想到了父类和子类,多态,接口等等。这部分是面向对象的主要内容,但并非全部内容。我在日常工作中,常常见到一些编码人员(测试或开发)写的代码是这样的,一个类套一个类,一个继承一个,十七八个类这么继承下来,使后续的维护者一头雾水。有时候维护者想要修改一些东西,不知道该改哪个类。这就说明原作者的设计过头了。所谓的“设计过度”的历史遗留代码,是我在工作中遇到的一个很常见的实际问题。

继承可能是这样的:

 

 

这样由上往下,从父类到子类。子类具有父类的属性和方法,并且有自己独有的新的属性和方法。

假设现在有一个在线电影网站要做自动化(这个网站大多数页面都带头部导航栏,导航栏里包括了“电影”,“电视剧”,“综艺”等菜单链接。),该自动化脚本的作者想要用页面对象模式封装这些页面。由于这位测试人员学过继承,于是他在测试框架里写了这样的类:

这是最典型的错误:滥用继承。

错误的点在于带导航栏的页面和不带导航栏的页面,不应该划分为两个类。

设想以下场景:

如果有一天需求变了。该网站支持了一批从第三方接入的用户(这也是一个我遇到过的实际需求噢)。对于这批新用户,要新增一种新版的头部导航栏,有些链接到原有内容,有些链接到这批用户独享的内容。网站改版成新旧导航栏并存。对老用户只开放老版导航栏,对第三方接入的新用户只开放新版导航栏。而页面本体没有其他任何变化。那么按照这种设计就会变成这样:

然后问题就来了:

页面1、2、3和7、8、9除了导航栏不一样以外,内容是完全一样的。

而只有页面10是专属于新的用户类型才能访问的页面。

此时,页面123和789里完全一样的内容写了两遍。那么日常维护量就变成了两倍。为了解决这种问题,需要引入组合模式。

三、加入组合模式

所谓组合模式,是这样的:

 

 引入了组合模式后,页面对象模式是这样的:

于是,在刚才的RegisterPage类里加入了导航栏的实例之后,这个页面的代码就是类似于这样的: 

仅仅只增加了一行代码,但是这个页面就得到了导航栏类的所有功能。假设导航栏里提供了goto_xxx_page()这样的方法,那么在调用时,只要

register_page.nav.goto_xxx_page()

这样就能在registerpage类里调用到导航栏类里的方法。

这样,就通过组合的方式,实现了页面之间功能更好的抽象。回头看那个导航栏发生变化的需求,一开始如果用了组合模式,那这个就不需要重复定义页面789了。

最后我们记住设计的原则:

把页面里可重用的模块,看作一个又一个的小页面。在页面类里通过组合的方式,把这些小页面组合进来。而不是搞一个复杂的继承树,一层套一层。

最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】

 全套资料获取方式:点击下方小卡片自行领取即可

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【图像分类】基于LIME的CNN 图像分类研究(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 💥1 概述 基于LIME(Local Interpretable Model-Agnostic Explanations)的CNN图像分类研究是一种用于解释CNN模型的方法。LIME是一…

【UE5 多人联机教程】04-加入游戏

效果 步骤 1. 新建一个控件蓝图,父类为“USC_Button_Standard” 控件蓝图命名为“UMG_Item_Room”,用于表示每一个搜索到的房间的界面 打开“UMG_Item_Room”,在图表中新建一个变量,命名为“Session” 变量类型为“蓝图会话结果…

自恢复保险丝(PPTC)的金属材料说明

保险丝大家都是知道的,但保险丝当中的自恢复保险丝(PPTC)可能就不太了解的。 其实PPTC自恢复保险丝与大家所认识的保险丝一样,都是起到限流作用,达到电路防护效果。简单来说就是一旦电路中的电流超过所规定的电流时&am…

【数据结构】二叉树详解(3)

⭐️ 前言 ✨ 往期链接:【数据结构】二叉树详解(1) 在第一篇二叉树文章中,我们探讨了二叉树的链式结构定义与实现。二叉的遍历包含( 前序/中序/后序遍历 )及代码实现和递归流程图的详细讲解。还有一些二叉树的其他接口定义与实现,包含 Binar…

【vue3】vue3的一般项目结构、成功显示自己的vue3页面

一、vue3的一般项目结构 Vue 3并没有规定特定的项目结构,因此您可以根据项目的需求和个人偏好来组织您的Vue 3项目。以下是一个常见的Vue 3项目结构示例,供参考: your-project/|- public/| |- index.html # 应用程序的入口HTML文件…

【Matlab】基于粒子群优化算法优化BP神经网络的时间序列预测(Excel可直接替换数据)

【Matlab】基于粒子群优化算法优化BP神经网络的时间序列预测(Excel可直接替换数据) 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码5.1 fun.m5.2 main.m 6.完整代码6.1 fun.m6.2 main.m 7.运行结果 1.模型原理 基于粒子群优化算法(Pa…

ubuntu 18.04 磁盘太满无法进入系统

安装了一个压缩包,装了一半提示磁盘空间少导致安装失败。我也没在意,退出虚拟机打算扩展硬盘。等我在虚拟机设置中完成扩展操作,准备进入虚拟机内部进行操作时,发现登录不进去了 shift 登入GUN GRUB设置项的问题 网上都是在开机…

持续贡献开源力量,棱镜七彩加入openKylin

近日,棱镜七彩签署 openKylin 社区 CLA(Contributor License Agreement 贡献者许可协议),正式加入openKylin 开源社区。 棱镜七彩成立于2016年,是一家专注于开源安全、软件供应链安全的创新型科技企业。自成立以来&…

Cesium态势标绘专题-圆角矩形(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

剑指offer41.数据流中的中位数

我一开始的想法是既然要找中位数,那肯定要排序,而且这个数据结构肯定要能动态的添加数据的,肯定不能用数组,于是我想到了用优先队列,它自己会排序都不用我写,所以addNum方法直接调用就可以,但是…

小创业公司死亡剧本

感觉蛮真实的;很多小创业公司没有阿里华为的命,却得了阿里华为的病。小的创业公司要想活无非以下几点: 1 现金流,现金流,现金流; 2 产品,找痛点,不要搞伪需求; 3 根据公司…

让婚礼策划展示小程序成为你的必备利器

在当今互联网时代,微信小程序已经成为了很多企业和个人展示自己产品和服务的重要渠道。如果你想学习微信小程序开发,下面将为你介绍一些基本步骤。 首先,你需要注册并登录一个第三方小程序制作平台,比如乔拓云平台。这些平台提供了…

Git-分布式版本控制工具

Git仓库:本地和远程 获取git仓库: 本地初始化Git仓库(创建空目录,右键git bansh,执行git init)远程仓库克隆,git clone 远程仓库地址 版本库:.git隐藏文件夹,储存配置信…

【SCI一区】互联燃料电池混合动力汽车通过信号交叉口的生态驾驶双层凸优化(Matlab代码实现)

目录 💥1 概述 1.2 电动车动力学方程 1.3 电池模型 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码、数据、文章讲解 💥1 概述 文献来源: 随着车辆互联性的出现,互联汽车 (CVs) 在增强道路安全、改…

Android平台如何实现第三方模块编码后(H.264/H.265/AAC/PCMA/PCMU)数据实时预览播放

技术诉求 我们在做GB28181设备对接模块和RTMP直播推送模块的时候,遇到这样的技术需求,设备(如执法记录仪)侧除了采集传统的摄像头外,还需要对接比如大疆等第三方数据源,确保按照GB28181规范和RTMP协议规范…

量化交易——python数据分析及可视化

该项目分为两个部分:一是数据计算,二是可视化,三是MACD策略 一、计算MACD 1、数据部分 数据来源:tushare 数据字段包含:日期,开盘价,收盘价,最低价,最高价&#xff0c…

C# 用队列实现栈

225 用队列实现栈 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 实现 MyStack 类: void push(int x) 将元素 x 压入栈顶。 int pop() 移除并返…

数分面试题-SQL常见面试题型1

目录标题 1、连续时间问题1.1 最近一周内的活跃天数1.2 每个用户一周内最大连续活跃天数1.3 计算截至当前,每个用户已经连续签到的天数 2、时间间隔问题举例3、sql窗口分析函数3.1 有一个日志登陆列表,获取用户在某个页面停留时长3.2 寻找至少连续出现3次…

苍穹外卖-day08 java实现 微信支付

苍穹外卖-day08 课程内容 导入地址簿功能代码用户下单订单支付 功能实现:用户下单、订单支付 用户下单效果图: 订单支付效果图: 1. 导入地址簿功能代码 1.1 需求分析和设计 1.1.1 产品原型 地址簿,指的是消费者用户的地址信息&…

GPT-3.5:ChatGPT的奇妙之处和革命性进步

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…