浅谈cypress的PO模式

浅谈cypress的PO模式

一、环境部署

1、安装Node.js
[https://nodejs.org/zh-cn/](https://nodejs.org/zh-cn/)
2、安装cypress
1) 新建项目目录,例如 /Users/dabing/cypress_public
2) 命令行进入该目录,并执行下面  命令
	npm init   --生成package.json文件
	npm config set registry  https://registry.npm.taobao.org   --修改镜像库地址
	npm install cypress --save -dev  --安装cypress
3、打开cypress
方法一:

进入 /Users/dabing/cypress_public/node_modules/.bin目录
cypress open

方法二:

npx cypress open

方法三:

1)修改package.json,新增scripts代码段,例如:

"script"{
	"cypress":"cypresss open"
}

2)执行 npm run cypress

执行完后会生成cypress文件夹
执行完后会出现这四个文件夹
写用例是在这个目录下
在这里插入图片描述

二、UI与Api的第一个例子

直接上代码,备注也注明

// context相当于测试套件
context('登录',()=> {
    // ui访问示例
    it ('输入正确的用户名和密码,可以登录成功', () => {
        // 访问的url,相当于selenium里的get
        cy.visit("http://pc-pp.xingfuyikatong.com/login#none")
        cy.get('#normalLoginTab').click()
        cy.get('#username').type('10111111111')
        cy.get('#pwd').type('lc123123')
        cy.get('#formlogin > .item-fore5 > .login-btn > .btn-img').click()
        // should用于断言使用
        cy.get('span > a').should('contain','退出')
    })
    // 接口访问示例
    it ('输入错误的用户名和密码,登录失败', () => {
        cy.request({
            url:'https://api-pp.xingfuyikatong.com/login',
            // method是请求方法,默认情况是GET,还可以是POST、PUT、DELETE等
            method:'post',
            // 是否将body的值转换为url encoded并设置x-www=form-urlencoded标头
            form:true,
            // body是请求体
            body:{
                'loginName':'10111111111',
                'password':'error',
                'passportIdKey':'',
                'platform':'H5'
            }
        }).then(response=>{
            // 断言
            expect(response.status).to.be.equal(200)
            expect(response.body.msg).to.be.equal('密码不正确!')
        })
    })
})

三、PO设计模式

最早以前自动化方面接触的工具可能就是QTP了,该工具就是将所有元素都封装成对象,到至今很多演变的工具或者设计思想也都沿用于此,也是为之不多的能做c/s框架的UI自动化。随之更多轻便的工具衍生,cypress的轻便及高效的开发能力,确实得到了不少人的青睐。再次也只是针对以前用selenium时的PO设计思想套用到cpyress中。
以下是设计的目录结构
在这里插入图片描述

PO设计模式主要两大概念,封装业务对象、封装页面常见的业务流

1、封装对象识别属性–json–elementConfig.json
{
    "loginPage":{
        "username": "#username",
        "password": "#pwd",
        "submit": "#formlogin > .item-fore5 > .login-btn > .btn-img",
        "accountError": "#login_error",
        "exit": "span > a"
    }
}
2、封装cypress可以识别的对象–loginpage.js–>class LoginPage
3、封装常见业务方法–loginpage.js–>class LoginPage
import locator from './elementConfig.json'
export default class LoginPage {
    constructor() {
        this.url = 'http://pc-pp.xingfuyikatong.com/login'
    }
    // 封装页面对象
    get getByUsername(){
        return cy.get(locator.loginPage.username)
    }
    get getByPassword(){
        return cy.get(locator.loginPage.password)
    }
    get getBySubmit(){
        return cy.get(locator.loginPage.submit)
    }
    get getByAccountError(){
        return cy.get(locator.loginPage.accountError)
    }
    get getByExit(){
        return cy.get(locator.loginPage.exit)
    }
    visit(){
        cy.visit(this.url)
    }
    // 封装常见业务流
    login(name,pwd){
        cy.get('#normalLoginTab').click()
        cy.wait(1)
        if(name!==""){
            this.getByUsername.type(name)
        }
        if(pwd!==""){
            this.getByPassword.type(pwd)
        }
        this.getBySubmit.click()
    }
}
4、编写测试用例:testLogin.js–调用loginpage.js–>class LoginPage
import LoginPage from "./page/loginPage";
import 'cypress-xpath'

context('登录',()=> {
    it ('输入正确的用户名和密码,可以登录成功', () => {
        let login = new LoginPage()
        login.visit()
        login.login('10111111111','lc123123')
        login.getByExit.should('contain','退出')
    })

    it ('输入错误的用户名和密码,登录失败', () => {
        let login = new LoginPage()
        login.visit()
        login.login('10111111111','error')
        login.getByAccountError.should('contain','您输入的用户名或密码错误!')
    })
})

四、常用定位元素的命令

describe('选择器及元素定位',()=>{
    beforeEach(()=>{
        cy.visit('https://example.cypress.io/commands/querying')
    })

    // -------------------------选择器--------------------------
    it('方式1:id 选择器',()=>{
        cy.get('#query-btn').should('contain','Button') //BDD
    })
    it('方式2:标签 选择器',()=>{
        cy.get('button').should('contain','Button') //BDD
    })
    it('方式3:属性 选择器',()=>{
        cy.get('[id="query-btn"]').should('contain','Button') //BDD
    })
    it('方式4:标签+属性 选择器',()=>{
        cy.get('button[id="query-btn"]').should('contain','Button') //BDD
    })
    it('方式5:id+属性 选择器',()=>{
        cy.get('#inputName[placeholder="Name"]').type('huice')
    })

    it('方式6:class 选择器',()=>{
        cy.get('.query-btn').should('contain','Button')
    })

    it('方式7:级联混合 选择器',()=>{
        cy.get('#querying .well>button').should('contain','Button')
    })

    it('方式8::nth-child(n)',()=>{
        cy.get('.query-ul').get(':nth-child(2)').should('contain','Two')
    })


    // ------------------------元素获取-----------------------

    // 方法一:get,略
    it('contains 一',()=>{
        cy.get('.query-list').contains('bananas').should('have.class', 'third')
    })
    it('contains 二',()=>{
        cy.get('#querying').contains('ul', 'oranges').should('have.class', 'query-list')
    })

    it('find 二',()=>{
        cy.get('#querying').find('.first').should('contain','first')
    })

    it('with',()=>{
        cy.get('.query-form').within(() => {
            cy.get('input:first').should('have.attr', 'placeholder', 'Email')
            cy.get('input').first().should('have.attr', 'placeholder', 'Email')
            cy.get('input').eq(0).should('have.attr', 'placeholder', 'Email')

            cy.get('input:last').should('have.attr', 'placeholder', 'Password')
        })
    })

})

  // 其它辅助方法:
    // .children():获取dom元素的子元素
    // .parents():获取dom元素的所有父元素
    // .parent():获取向上级的第一层父元素
    // .siblings():获取所有同级元素(兄弟元素)
    // .first():匹配找到的第一个元素
    // .last():匹配找到的最后一个元素
    // .next():匹配紧跟着的下一个同级元素
    // .nextAll:匹配该对象之后的所有同级元素
    // .nextUntil():匹配该对象之后的所有同级元素,直到遇到Until中定义的元素为止
    // .prev:与next()相反
    // .prevAll:与nextAll相反
    // .prevUntil():与nextUntil相反
    // .each():遍历所有子元素
    // it('each遍历所有元素',()=>{
    //     cy.get('.query-ul').each(($li) => {
    //      cy.log($li.text())
    //     })
    // })
    // // .eq(index):根据索引获取指定元素
    // it.only('eq获取指定元素',()=>{
    //     cy.get('.query-ul').get('li').eq(1).should('contain','Two')
    // })

    // -----------------------元素常见操作--------------------------
    // .click()
    // .dblclick()
    // .rightclick()
    // .type()
    // .clear()
    // .check()
    // .uncheck()
    // .select('huice') .select(['huice1','huice2'])
    // .trigger()
    // .visit()
    // .reload()/.reload(true)  --强制刷新
    // .viewpoint(1024,768) --设置窗口大小
    // 后退:.go('back')/.go(-1)  前进:.go('forward')/.go(1)
    // 判断元素是否可见:.should('be.visible')/.should('not.be.visible')
    // 判断元素是否存在:.should('exist')/.should('not exist')
    // 操作被覆盖的元素,例如:.click({force:true})
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值