前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端测试框架Cypress-测试用例组织和编写

前端测试框架Cypress-测试用例组织和编写

作者头像
搁浅同学
发布2022-07-21 14:52:56
9220
发布2022-07-21 14:52:56
举报

在深圳这个雨天!听首歌曲吧,一起阅读呢

1.Cypress用例组织

接着上一篇,现在来说说cypress的用例组织结构是怎样的。首先下面的代码

代码语言:javascript
复制
/// <reference types="cypress" />
describe("登录",function(){
    const username="jane.lane"
    const password="password123"
    before(function(){
        cy.log('所有测试用例执行前执行1次')
    })
    after(function(){
        cy.log("所有测试用例都执行完后执行1次")
    })
    beforeEach(function(){
        cy.log("每个测试用例前执行1次")
    })
    afterEach(function(){
        cy.log("每个测试用例执行完成后执行1次")
    })
    context("HTML表单登录测试",function(){
        //测试用例
        it("登录成功,跳转到dashboard页",function(){
            //访问刚才的登录链接
            cy.visit("http://localhost:7077/login")
            cy.get('input[name=username]').type(username)
            cy.get('input[name=password]').type(password)
            cy.get('form').submit()
            //断言
            cy.url().should('include','/dashboard')
            cy.get('h1').should('contain','jane.lane')

        })
        it('测试1=1',function(){
            expect(1).to.equal(1)
        })
    })
}) 

上面的代码就是一个测试脚本,有两个测试用例。

对于一个可执行的测试来说,必须具备

1.1、describe() -测试套件,测试套件里面可以设置context(),也可以嵌套测试套件describe(),context其实是describe()的别名

1.2、it() -代表一个测试用例,而且一个测试套件里面必须含一个测试用例it(),不然会报错

1.3、其他before(),after(),beforeEach(),afterEach(),称为钩子函数,钩子函数不能放在测试用例it()里面,这几个钩子函数相当于python-unittest的setUpClass(),setup(),teardown(),teardownClass()

1.4、describe(),context(),it(),第一个参数描述,可以随便定义,第二个参数是一个匿名函数

我们可以运行下这个脚本,可以看得出来这个两个it()测试用例执行情况,来说明钩子函数运行情况,如何运行的,请看以下运行结果

由上面运行结果可以看得出,before()在运行测试用例执行1次。after()在所有测试用例执行完成后执行1次,beforeEach()在每个测试用例执行前都执行1次,afterEach()在每个测试用例执行完成后都执行1次

所以我们编写测试用例,要按照上面的结果进行编写,钩子函数选择可以按需选择

2.测试用例可以选择性执行

在python-unittest里面测试用例的执行可以加一些装饰器,来跳过一些测试用例的执行,同样的在cypress里面同样也同样的功能,一般分为以下几种情况:

2.1、排除测试套件/测试用例-skip

代码语言:javascript
复制
/// <reference types="cypress" />
describe("登录",function(){
    const username="jane.lane"
    const password="password123"
    context("HTML表单登录测试",function(){
        //测试用例
        it.skip("登录成功,跳转到dashboard页",function(){
            //访问刚才的登录链接
            cy.visit("http://localhost:7077/login")
            cy.get('input[name=username]').type(username)
            cy.get('input[name=password]').type(password)
            cy.get('form').submit()
            //断言
            cy.url().should('include','/dashboard')
            cy.get('h1').should('contain','jane.lane')

        })
        it('新增测试,验证before()只执行一次',function(){
            expect(1).to.equal(1)
        })
        it('新增测试,验证beforeEach执行次数跟测试用例个数相同',function(){
            expect(1).to.equal(1)
        })

    })

})
describe.skip('测试1=1',function(){
    it('测试1=1',function(){
        expect(1).to.equal(1)
    })
    context('排除测试套件',function(){
        it('测试1!=2',function(){
            expect(1).not.to.equal(2)
        })
    })
})

在decribe后面加skip或者在context后面加skip,就可以排除无须执行的测试用例套件,在执行用例时,不会再执行该测试套件下的测试用例

在it后面加skip,再执行测试用例,有skip的用例,执行不会再执行。

2.2、包含测试用例套件/测试用例-only

把上面的skip换成only,代码如下:

代码语言:javascript
复制
/// <reference types="cypress" />
describe.only("登录",function(){
    const username="jane.lane"
    const password="password123"
    context("HTML表单登录测试",function(){
        //测试用例
        it("登录成功,跳转到dashboard页",function(){
            //访问刚才的登录链接
            cy.visit("http://localhost:7077/login")
            cy.get('input[name=username]').type(username)
            cy.get('input[name=password]').type(password)
            cy.get('form').submit()
            //断言
            cy.url().should('include','/dashboard')
            cy.get('h1').should('contain','jane.lane')

        })
        it('新增测试,验证before()只执行一次',function(){
            expect(1).to.equal(1)
        })
        it('新增测试,验证beforeEach执行次数跟测试用例个数相同',function(){
            expect(1).to.equal(1)
        })

    })

})
describe('测试1=1',function(){
    it('测试1=1',function(){
        expect(1).to.equal(1)
    })
    context('排除测试套件',function(){
        it('测试1!=2',function(){
            expect(1).not.to.equal(2)
        })
    })

被添加only的decribe(),在执行测试脚本时,只会执行第一个describe测试套件,第二不会再执行。如果在describe没有被添加only,在it被添加only同样的道理。

2.3、动态忽略测试用例

请看以下脚本的代码:

代码语言:javascript
复制
/// <reference types="cypress" />
describe("登录",function(){
    const username="jane.lane"
    const password="password123"
    context('HTML表单登录测试',function(){
        it('登录成功,跳转到dashboard',function(){
            //如果传进来的runFlag为1,则执行
            if(Cypress.env('runFlag')==1){
                cy.visit("http://localhost:7077/login")
              cy.get('input[name=username]').type(username)
              cy.get('input[name=password]').type(password)
              cy.get('form').submit()
              //断言
              cy.url().should('include','/dashboard')
              cy.get('h1').should('contain','jane.lane')
            }else{
                this.skip()
            }
        })
        it('测试1=1',function(){
            expect(1).to.equal(1)
        })
    })
})

上面测试用例做了一个if-else的判断,判断runFlag是否等1来判断是否执行,怎么执行呢?

我们可以通过执行以下命令行把runFlag传进来,如下:

yarn cypress:open --env runFlag=1

第1个和第二个测试用例均被执行,运行结果如下:

如果传runFlag=0,那么只有第二个测试用例被执行,第一个测试用例被标记未执行,如下:

3.动态生成测试用例

比如我们编写测试用例时候,如果碰到多条测试用例执行步骤和检查步骤完全一样,只有输入输出不一致。我们可以通过编写一个js作为测试用例数据输入,另外一个js作为测试脚本,如下:

第一个数据数据的js文件,代码如下:

代码语言:javascript
复制
//导出一个数组对象,数组里面每一个对象是一组数据
export const testLoginUser=[
    {
        summary:"login pass",
        username:"jane.lane",
        password:"password123"

    },
    {
        summary:"login fail",
        username:"jane.lane",
        password:"password"

    }
    ]

第二个测试脚本的js文件,代码如下:

代码语言:javascript
复制
/// <reference types="cypress" />
//导入第一个数据js文件的数组对象,{testLoginUser}导入是ES6对象解构
import {testLoginUser} from './autoGenTestLogin/testLogin.data'
describe('登录',function(){
    context('HTML表单登录测试',function(){
    //通过for of 循环遍历数组对象数据,创建it测试用例
        for(const user of testLoginUser){
            it(user.summary,function(){
                cy.visit('http://localhost:7077/login')
                cy.get('input[name=username]').type(user.username)
                cy.get('input[name=password]').type(user.password)
                cy.get('form').submit()
                cy.get('h1').should('contain',user.username)
            })
        }
    })
})

最后执行结果如下:

4.总结

这次主要介绍的是测试用例组织结构、测试用例选择执行、动态生成测试用例。测试用例需要按照describe-(context)-it结构进行编写,不然在执行的时候会报错。其他的就没有什么好主意的了。和其他的测试框架也有点类似。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 暴走的软件测试Tester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档