自动化测试框架[Cypress PO模式]

自动化测试框架[Cypress PO模式]【附源码】在Cypress中并不认为PO是个很好的模式,Cypress认为跨页面共享逻辑是一个反模式(Anti-Pattern),在Cypress中,它提供了很多方式,允许用户通过更简单的方式直接设置被测应用程序达到的待测试状态,不需要再不同页面一遍又一遍的执行相通操作

大家好,又见面了,我是你们的朋友全栈君。

Cypress的PO模型

将元素定位器剥离

首先在工程的Cypress路径下新建一个pages目录,然后在该目录下新建一个JS文件,并命名为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, password){ 
   
		cy.get(this.userName).type(username)
		cy.get(this.password).type(password)
		cy.get(this.form).submit()
	}
}

然后在Cypress路径下的integration路径下新建一个JS文件,并命名为testLogin.js

//testLogin.js
/// <reference types="cypress" />
import LoginPage from "../pages/login"
describe('登录测试,PageObject模式', function () { 
   
    const username = 'davie.yang'
    const password = 'yangdawei'
    it('登录成功', function () { 
   
    	// 创建pageobject实例
        const loginInstance = new LoginPage()
        loginInstance.isTargetPage()
        loginInstance.login(username, password)
        cy.url().should('include', '/dashboard')
    })
})

改造login.js

//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, passWord){ 
   
		this.username.type(userName)
		this.password.type(passWord)
		this.form.submit()
	}
}

在pages路径下新建JS文件,并命名为mainPage.js

//mainPage.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)
	}
}

更新testLogin.js文件,验证登陆成功后跳转到mainPage页面

//testLogin.js
/// <reference types="cypress" />
import LoginPage from "../pages/login"
import mainPage from "../pages/mainPage"
describe('登录测试,PageObject模式', function () { 
   
    const username = 'davie.yang'
    const password = 'yangdawei'
    it('登录成功', function () { 
   
        const loginInstance = new LoginPage()
        loginInstance.isTargetPage()
        loginInstance.login(username, password)
        cy.url().should('include', '/dashboard')
        const mainInstance = new mainPage()
        mainInstance.isTargetPage()
        mainInstance.welComeText.should('contain', 'davie.yang')
    })
})

进一步更新,将每个页面都公用的部分再次剥离,在pages路径下新建一个JS文件,并命名为commonPage.js

//commonPage.js
export default class CommonPage { 
   
    constructor() { 
   
        //构造函数,可以为空。
        //如果不为空,应该是所有 page 都会用到的变量。
    }
    isTargetPage() { 
   
        cy.url().should('eq', this.url)
    }

}

然后更新login.js文件

//login.js
import CommonPage from './commonPage'
export default class LoginPage extends CommonPage { 
   
    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, passWord) { 
   
        this.username.type(userName)
        this.password.type(passWord)
        this.form.submit()
    }
}

更新pages文件夹下的mainPage.js文件

import CommonPage from './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)
    }
}

到此一个PO模式实现完毕

Cypress的PO模式弊端

如果一个测试需要访问多个页面对象,这就意味着测试过程中需要初始化多个页面对象的实例,如果大多数页面对象需要 登陆才能访问,则每次初始化都需要先登录再访问,因为只有登陆后才能重用cookie,这无疑会增加测试执行的时间

因此在Cypress中并不认为PO是个很好的模式,Cypress认为跨页面共享逻辑是一个反模式(Anti-Pattern),在Cypress中,它提供了很多方式,允许用户通过更简单的方式直接设置被测应用程序达到的待测试状态,不需要再不同页面一遍又一遍的执行相通操作,这个更简单的方式就是***Custom Commands***

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137793.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • javaweb项目连接MySQL数据库_php实现评论回复功能

    javaweb项目连接MySQL数据库_php实现评论回复功能Java+MySQL实现评论功能设计开发一、背景项目初始版本上线,有时间写点东西记录一下项目中的心得体会,通过这个项目学习了很多,要写下来的有很多,先从评论功能开始吧。由于项目需要增加评论功能,之前并无此方面的经验,因此项目开始的一段时间都在寻思着如何进行评论功能的设计。上网搜索一波…

    2022年10月1日
    0
  • 玩转ADB命令(ADB命令使用大全)

    玩转ADB命令(ADB命令使用大全)我相信做Android开发的朋友都用过ADB命令,但是也只是限于安装应用push文件和设备重启相关,根深的也不知道了,其实我们完全可以了解多一点,有一些不常用的场景我们至少应该知道它可以做到,比如,我们知道adbinstall却不知道adbshellamstart。前者是用来安装软件,后者用来打开软件,后者的一个使用场景让我对他重视:公司定制Android系统,在调试屏幕的时候要看是否满屏

    2022年5月13日
    35
  • job 定时任务的五种创建方式 || xxl-job 定时任务调度中心「建议收藏」

    一、job定时任务的创建方式1、使用线程创建job定时任务/***TODO使用线程创建job定时任务*@author王松*@date2019/9/14001422:12*/publicclassJobThread{publicstaticclassDemo01{staticlongcount…

    2022年4月15日
    104
  • Mozilla正在SpiderMonkey中测试JavaScript并行计算

    Mozilla正在SpiderMonkey中测试JavaScript并行计算

    2021年9月4日
    61
  • 2021年材料员-岗位技能(材料员)新版试题及材料员-岗位技能(材料员)考试试卷

    2021年材料员-岗位技能(材料员)新版试题及材料员-岗位技能(材料员)考试试卷题库来源:安全生产模拟考试一点通公众号小程序安全生产模拟考试一点通:硝化工艺题库来源:安全生产模拟考试一点通公众号小程序安全生产模拟考试一点通:硝化工艺考试内容是安全生产模拟考试一点通生成的,硝化工艺证模拟考试题库是根据硝化工艺最新版教材汇编出硝化工艺仿真模拟考试。2021年硝化工艺考试内容及硝化工艺考试报名1、【单选题】三不动火是指:没有经批准的动火作业票不动火;监护人不在现场不动火;()。(A)A、安全措施不落实不动火B、分析不合格不动火C、领导不在现场不动火2、【单选题】苯硝化

    2022年5月30日
    39
  • 倒排索引[通俗易懂]

    倒排索引[通俗易懂]倒排索引

    2022年4月24日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号