在简单看了cypress 官方文档后,就开始用上了,越用感觉越爽。 顺便提一句,官方文档太良心了,方方面面都讲到了,而且还有视频,可以切换语言。 下面就讲讲如何使用cypress搭建一个自动化框架。当然我还是初学者,市面上也没有太多的资料,都是入门级的,官方文档也只给你渔,不会提供鱼,自己折腾出来的,感觉像那么回事。
自动化测试工具,可以用来做自动化测试,也可以自动化做些重复工作,比如准备数据。
这里有一个页面,就是要填一些参数,点击按钮。页面不复杂,复杂的是各种参数,重复操作很多次。
1. 框架搭建
以下是最开始照着例子写的,比较简单,基本hard code了。
describe('Arrange class', function () {
it('Arrange on UAT!', function () {
cy.visit("http://xxx/allocate")
cy.get('[title="UAT"]').click()
cy.get(".ant-select-selection__placeholder").first()
.type("23123423452222")
cy.wait(100)
cy.contains("(23123423452222)").click()
cy.contains("+30 mins").click()
cy.get('[class="ant-select ant-select-enabled"]').last()
.click()
cy.contains("all levels").click()
cy.get('.ant-btn.ant-btn-primary').click()
for( var i =1; i<=10; i++){
cy.contains("+30 mins").click()
cy.wait(100)
cy.contains("+30 mins").click()
cy.get('.ant-btn.ant-btn-primary').click()
}
})
})
当然我们用selenium也可以实现,但是没有 cypress简单和执行效率高。
问题来了,按照使用要求,还有好多类似的场景,得改参数或者写好几个类似的文件来执行。还有各个环境,文件的数量倍数上升了。
于是乎,将函数参数化,将公共部分抽取出来,难记的参数写成JS对象,这样看起来就舒服多了。
function book(url,id,teacher,class_type,currentenv){
cy.visit(url)
cy.get(".ant-select-selection__placeholder").first()
.type(id)
cy.wait(100)
cy.contains(teacher).click()
cy.get('[class="ant-select ant-select-enabled"]').last()
.click()
cy.contains(class_type).click()
cy.get('.ant-btn.ant-btn-primary').click()
if (class_type == classType.PL20)
{
for( var i =1; i<=10; i++){
cy.contains("+30 mins").click()
cy.wait(100)
cy.get('.ant-btn.ant-btn-primary').click()
}
}
else{
for( var i =1; i<=10; i++){
cy.contains("+30 mins").click()
cy.wait(100)
cy.contains("+30 mins").click()
cy.get('.ant-btn.ant-btn-primary').click()
}
}
}
describe('Arrange classes on UAT', function () {
before
{
var url = host + `${ENV.UAT}` + "/class"
}
it('arrange GL', function () {
book(url,GL)
}
it('arrange PL20', function () {
book(url,PL20)
}
describe('Arrange classes on QA', function () {
before
{
var url = host + `${ENV.QA}` + "/class"
}
it('arrange GL', function () {
book(url,GL)
}
it('arrange PL20', function () {
book(url,PL20)
}
describe('Arrange classes on STG', function () {
before
{
var url = host + `${ENV.STG}` + "/class"
}
it('arrange GL', function () {
book(url,GL)
}
it('arrange PL20', function () {
book(url,PL20)
}
执行起来很爽,但新的问题又来了。运行一次,所有的环境都运行了。即一次运行了所有的用例集。 解决办法就是将公共部分剥离出来做一个文件,每个环境当一个用例集,其中的一个用例集大概是这个样子:
import {contury,classType,uat_teachers,uat_teacherid,qa_teachers,qa_teacherid,stg_teachers,stg_teacherid,ENV, book} from "./base"
describe('Arrange classes on QA', function () {
var url = host + ENV.QA + "/class"
it('arrange GL', function () {
if (contury == "CN")
{
book(url,qa_teacherid.AMOBILE,qa_teachers.AMOBILE,classType.CNGL)
}
else
{
book(url,qa_teacherid.AMOBILE,qa_teachers.AMOBILE,classType.USGL)
}
})
it('arrange PL20', function () {
if (contury == "CN")
{
book(url,qa_teacherid.BMOBILE,qa_teacherid.BMOBILE,classType.CNPL20)
}
else
{
book(url,qa_teacherid.BMOBILE,qa_teacherid.BMOBILE,classType.USPL20)
}
})
it('arrange PL40', function () {
if (contury == "CN")
{
book(url,qa_teacherid.CMOBILE,qa_teacherid.CMOBILE,classType.CNPL40)
}
else
{
book(url,qa_teacherid.CMOBILE,qa_teacherid.CMOBILE,classType.USPL40)
}
})
})
这样运行起来是有点爽,跑起来嗖嗖的,想运行哪个环境就运行哪个环境。
开始从一个简单的样例跑起功能来,然后抽离函数,接着抽离组织文件,一个简单的框架就有了雏形。更复杂的,也可以用这种方式来套用。
2. 集成CI
但是其还是基于GUI的。我们可以用CLI命令来执行它,命令大概是这样的:
你可以定义报告生成器可选项--reporter-options <reporter-options>参数:
cypress run --reporter junit --reporter-options mochaFile=result.xml,toConsole=true
cypress run --spec <spec>
运行某个单独的测试文件而不是所有的测试用例:
cypress run --spec "cypress/integration/examples/actions.spec.js"
运行*号匹配到的文件目录(注意:推荐使用双星号**):
cypress run --spec "cypress/integration/login/**/*"
运行指定多个测试文件:
cypress run --spec "cypress/integration/examples/actions.spec.js,cypress/integration/examples/files.spec.js"
跑出来的结果就是这样的:
将其放到CI上,定个时间,让其自动触发,每天早上一到办公室,数据已经自动准备好了,可以立即干活,效率提升了好多。这里用python写了几行代码,通过环境参数,跑不同的用例集,为什么这样,因为文档还没看完,用熟悉的方法来曲线救国了。
先定义一个环境参数列表:
然后定义一个自动运行的时间,工作日的9点:
python代码很简单,就是几个if else, 当然可以直接在构建里面写shell. 构建后可以将result xml结果展示出来,也可以将录屏幕的video archive 进来。这样就可以看到具体结果和执行时间。
好了,框架搭建起来了,也集成到了CI;跑自动化测试也可以这么弄,只是要多加点assertion 罢了。