Cypress系列(62)- 改造 PageObject 模式
如果想从头学起Cypress,可以看下面的系列文章哦
https://www.cnblogs.com/poloyy/category/1768839.html
PO 模式
PageObject(页面对象)模式是自动化测试中的一个最佳实践,相信很多小伙伴都知道的
PO 模式特征
- 将每个页面(或者待测试对象)封装成一个(class),类里面包含了页面上所有元素及它们的操作方法(单步操作或功能集合)
- 测试代码和被测页面代码解耦,使用 PO 模式后,当页面发生改变,无须改变测试代码,仅改页面代码
接下来就讲解下 Cypress 下如何使用 PO 模式
前期准备
启动 Cypress 提供的演示项目
cmd 窗口进入下面的文件夹
执行下面的命令
npm start
PO 模式代码
简单的 PageObject 模型栗子
待测试页面代码
在 C:\Users\user\Desktop\py\cypress-example-recipes\examples\logging-in__html-web-forms\cypress 文件夹下新建 pages 文件夹,并创建一个 login.js 待测试页面文件,代码如下
// login.js
export default class LoginPage {
constructor() { this.userName = 'input[name=username]'
this.password = 'input[name=password]'
this.form = 'form'
this.url = 'http://localhost:7077/login'
} isTargetPage() {
cy.visit('/login')
cy.url().should('eq', this.url)
} login(username, pwd) {
cy.get(this.userName).type(username)
cy.get(this.password).type(pwd)
cy.get(this.form).submit()
} }
测试用例文件
在 C:\Users\user\Desktop\py\cypress-example-recipes\examples\logging-in__html-web-forms\cypress\integration 文件夹下,创建一个 testLogin.js 测试用例文件,代码如下
import LoginPage from "../pages/login" context('登录测试,PO 模式', function () { const username = 'jane.lane'
const pwd = 'password123' it('登录成功', function () {
// 创建 po 实例
const loginInstance = new LoginPage()
loginInstance.isTargetPage()
loginInstance.login(username, pwd)
cy.url().should('include', '/dashboard')
}); })
测试结果
总结下
这样的 PageObject 模式代码只是把定位元素的元素定位表达式给剥离出来,并没有针对元素本身进行封装
针对元素本身进行封装的栗子
待测试页面代码
// login.js export default class LoginPage {
constructor() {
this.userNameLocator = 'input[name=username]'
this.passwordLocator = 'input[name=password]'
this.formLocator = 'form'
this.url = 'http://localhost:7077/login'
} get username() {
return cy.get(this.userNameLocator)
} get password() {
return cy.get(this.passwordLocator)
} get form() {
return cy.get(this.formLocator)
} isTargetPage() {
cy.visit('/login')
cy.url().should('eq', this.url)
} login(username, pwd) {
this.username.type(username)
this.password.type(pwd)
this.form.submit()
} }
跳转页面代码
当登录成功后,页面将跳转至 mainPage 页面,上面只写了 login 页面,这里写下跳转后的页面
// login.js export default class mainPage{
constructor() {
this.h1Locator = 'h1'
this.url = 'http://localhost:7077/dashboard'
} get welComeText() {
return cy.get(this.h1Locator)
} isTargetPage() {
cy.url().should('eq', this.url)
}
}
测试用例代码
测试用例代码和上面的栗子一样哦!不需要变!
测试结果
总结下
- login.js 和 mainPage.js 两个页面对象都有一个 isTargetPage() 函数来判断当前页面 URL 是否正确
- 那这里就将每个 page 都共用的部分再次剥离,放到一个新的 common page
- 然后每个 page 都继承自 common page(类似 selenium po 模式的 BasePage)
使用 common page 的栗子
commonPage.js 的代码
它也在 pages 文件夹下创建
export default class commanPage {
constructor() {
// 构造函数可以为空
// 如果不为空 应该是所有 page 都会用到的变量
} isTargetPage() {
cy.url().should('eq', this.url1)
}
}
login.js 的代码
// login.js
import commanPage from "./commonPage"; // 继承 commonPage
export default class LoginPage extends commanPage{
constructor() {
// 调用父类的构造方法
super()
this.userNameLocator = 'input[name=username]'
this.passwordLocator = 'input[name=password]'
this.formLocator = 'form'
this.url = 'http://localhost:7077/login'
} get username() {
return cy.get(this.userNameLocator)
} get password() {
return cy.get(this.passwordLocator)
} get form() {
return cy.get(this.formLocator)
} visitPage(){
cy.visit('/login')
} login(username, pwd) {
this.username.type(username)
this.password.type(pwd)
this.form.submit()
} }
mainPage.js 的代码
// login.js
import commonPage from "./commonPage"; // 继承 commonPage
export default class mainPage extends commonPage {
constructor() {
super()
this.h1Locator = 'h1'
this.url = 'http://localhost:7077/dashboard'
} get welComeText() {
return cy.get(this.h1Locator)
}
}
测试结果
测试结果和上面的栗子一样
Cypress 使用 PO 模式的总结
- Cypress 完全支持 PageObject 模式
- 但存在一个问题,如果一个测试需要访问多个页面对象,就意味着测试中要初始化多个页面对象实例(new Page())
- 如果一个页面对象需要登录才能访问(大部分场景都是这样),则每次初始化都需要先登录再访问(只有登录后才能重用 cookie),这无形增加了测试运行的时间
- Cypress 不认为 PO 模式是一个好模式,它认为跨页面共享逻辑是一个反逻辑,因为 Cypress 的实现原理与其他工具完全不同
- 那 Cypress 用什么方式来替代 PO 模式呢?答案就是下一篇要讲到的 Custom Commands
Cypress系列(62)- 改造 PageObject 模式的更多相关文章
- Cypress系列(63)- 使用 Custom Commands
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html Custom Commands 自定义命 ...
- Cypress系列(1)- Window下安装 Cypress 并打开
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 系统要求 Cypress 是一个被安装在 ...
- Cypress系列(69)- route() 命令详解
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 作用 管理控制整个网络请求 重要注意事项 ...
- 浅谈pageobject模式
先来看两段代码 代码1: package com.zlshuo.selenium.nonaming.pageobject; /** * @author leshuo * @version 2014年5 ...
- CDC不同模式在ODI体现系列之二 异步模式
CDC不同模式在ODI体现系列之二 异步模式 2 异步模式需要在数据库中做一些准备工作: 改数据为归档并启用logminer: SQL> shutdown immediate 数据库已经关闭. ...
- 【转】Android总结篇系列:Activity启动模式(lauchMode)
[转]Android总结篇系列:Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些 ...
- PageObject模式的层次结构
做过UI自动化的都晓得,在做UI自动化时定位特别依赖页面,一旦页面发生变更就不得不跟着去修改页面定位. 在webdriver中,假设你想对一个元素定位操作,那么你可能会编写下面的代码: driver. ...
- Spartan6系列之芯片配置模式详解
1. 配置概述 Spartan6系列FPGA通过把应用程序数据导入芯片内部存储器完成芯片的配置.Spart-6 FPGA可以自己从外部非易失性存储器导入编程数据,或者通过外界的微处理器.DSP等对 ...
- Cypress系列(70)- server() 命令详解
如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 作用 启动服务器以开始将响应路由到 cy ...
随机推荐
- 【问题】【SpringBoot】记一次springboot框架下用jackson解析RequestBody失败的问题
最近项目中遇到了一个问题,费好大劲才发现问题所在,并且修复了问题,下面分享一下这个问题的定位和修复的新路旅程. 先说下背景:该项目用的是SpringBoot框架,主要功能为对外提供一些Restful ...
- webstorm编写vue、react 将大驼峰组件命名转换成短横杠命名
大家好!我是木瓜太香,精通 webstorm 与常见前端技术的工程师,偶尔也在b站搞一些 webstorm 技巧教学,今天给大家带来的是大驼峰小驼峰快速转换短横杠命名或者下划线命名的方式. 开发中我们 ...
- 一位北漂12年IT工程师的年终总结
Hi,我叫李振良,来自河南周口农村的一个普通家庭,如今来北京已经12年了,我是那种没有大学背景.没有聪明头脑.没有人脉的奋斗青年,但我又是那种不甘于现状,一直想做最好的那个人! 2019年已悄然离去, ...
- [业界方案] 用SOFATracer学习分布式追踪系统Opentracing
[业界方案] 用SOFATracer学习分布式追踪系统Opentracing 目录 [业界方案] 用SOFATracer学习分布式追踪系统Opentracing 0x00 摘要 0x01 缘由 &am ...
- 20190925-05Redis五大数据类型之String 000 026
- RocketMQ生产部署架构如何设计
前言 看了我们之前的文章,相信小伙伴们对RocketMQ已经有了一个初步的了解,那么今天我们就来聊一聊具体如何来设计一套高可用的生产部署架构. 在聊如何设计这套架构的同时,我们再补充一些之前没提到的知 ...
- 【原创】解BUG-xenomai内核与linux内核时间子系统之间存在漂移
版权声明:本文为本文为博主原创文章,转载请注明出处.如有问题,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 一.问题起源 何为漂移?举个例子两颗32.768kH ...
- Intersection of Two Prisms(AOJ 1313)
原题如下: Suppose that P1 is an infinite-height prism whose axis is parallel to the z-axis, and P2 is al ...
- Django 多页面间参数传递用session方法(Django七)
由一个页面跳转至另一个页面可以有render中携带几个参数,如下:照上例便在跳转到homepage页面后使用传递的四个参数了 但问题是如何在由homepage跳转到其他页面时仍可以使用这四个参数呢?我 ...
- oracle数据库备份、还原命令及常见问题(待补充)
1.oracle数据库的备份:先查空表——将结果全选复制为insert语句——将语句执行后导出 先select 'alter table '||table_name||' allocate exten ...