设置全局URL
为了绕过同源策略,当Cypress开始运行测试时,会在localhost上打开一个随机端口进行初始化,知道遇见第一个cy.visit()
命令里的URL才匹配被测应用程序的URL,可以在cypress.json
中设置baseUrl以减少代码冗余
设置好baseUrl后,不仅可以在运行时节省Cypress匹配被测应用程序的URL的时间,还可以在编写待访问的URL时候忽略baseUrl,直接写后面的路径
避免访问多个站点
Cypress不支持在一个测试用例里访问多个不同域名的URL,否则Cypress会直接报错,如果是同一个超域下的不同子域是允许的
特别的显式等待
在其他的测试框架中,如Selenium会经常用到sleep()
或者wait()
,但是在Cypress中无需使用显式等待,Cypress自带Retry特性
停用条件测试
在实际的测试过程中经常遇到一个场景"判断一个元素是否存在,如果存在则执行A操作,如果不存在则执行B操作",在Cypress中这种场景叫做条件测试但是在Cypress中条件测试被认为是测试执行不稳定的因素
,因此在Cypress中建议通过指定前置测试条件来避免不确定行为,也就是说当有A、B两个策略时,指定测试前置条件从而让A或B一定发生
前置条件的构造,可以通过修改DB直接获得,也可以根据业务特性使用API或者UI的方式构造,总之指导思想是A、B必定会执行其一
实时调试和中断
Cypress有两种Debug方式
.debug()
当定位问题时,可以使用.debug()
函数来调试,.debug()
命令返回上一条命令产生的结果
.debugger
Cypress测试代码和被测应用运行在同一个循环中,这意味着可以访问和控制页面上运行着的代码
不能再测试代码中使用debugger,如下写法是不工作的,Cypress是异步的,当执行如下cy.visit()
时,Cypress并没有立刻运行测试代码,debugger
自然就不会有什么用
运行时的截图和录屏
Cypress的截图和录屏能力非常强大
默认自动截图
在以cypress run方式运行测试时,测试发生错误的话Cypress会自动截图,并默认保存在/cypress/screenshots/
路径下
自定义截图
也可以在代码中自定义截图,无论测试成功或失败,使用.screenshot()
即可
代码示例
fileName是保存图片的名称,图片默认保存在cypress/screenshots
文件夹下,可以在cypress.json中修改此路径,配置项是screenshotsFolder
,也可以通过options参数来改变screenshot的默认行为
参数 | 默认值 | 描述 |
Log | TRUE | 在命令日志中显示 |
Blackout | [] | 此参数接受一个数组类型的字符选择器,该选择器匹配的元素会被涂黑,此选项在capture是runner时不起作用 |
Capture | ‘fullPage’ | 决定截图截取测试运行器的哪个部分,此参数仅跟在 |
clip | null | 用于裁剪最终屏幕截图图像的位置和尺寸(以像素为单位),格式为:{x:0,y:0, width:100, height:100} |
disableTimersAndAnimations | TRUE | 如果为TRUE,则在截屏时禁止JavaScript计时器(setTimeout, setInterval等)和CSS动画运行 |
padding | null | 用于更改元素屏幕截图尺寸的填充,此属性仅适用于元素屏幕截图,格式为:padding:[‘background-color:#ff7f50;’] |
scale | FALSE | 是否缩放应用程序以适合浏览器窗口,当capture为runner时,强制为TRUE |
timeout | responseTimeout | timeout时间 |
onBeforeScreenshot | null | 非因测试失败截图钱,要执行的回调函数,档次参数用于元素屏幕截图时,他的参数是被截取的元素,当此参数应用于其他截图时,它的参数是document本身 |
onAfterScreenshot | null | 非因测试失败截图后,要执行的回调函数,当此参数应用于元素屏幕截图时,第一个参数是被截取的元素,当此参数用于其他截图时,第一个参数是document本身,第二个参数是有关屏幕截图的属性 |
通过onBeforeScreenshot和onAfterScreenshot可以在截图发生前或后应用自定义行为
断言最佳实践
- Cypress的断言基于当下流行的Chai断言库,并且增加了对Sinon-Chai,Chai-jQuery断言库的和支持
- Cypress支持BDD(expect/should)和TDD(assert)格式的断言
Cypress命令有内置的断言,并且这些断言使得命令自动重试,从而确保命令成功(或者超时后失败),例如
内置的Cypress命令断言
命令 | 断言事件 |
cy.visit() | 期望访问返回的status code是200 |
cy.request() | 期望远程server存在并且能连通 |
cy.contains() | 期望包含某些字符的页面元素能在DOM里找到 |
cy.gett() | 期望页面元素最终能在DOM页面里找到 |
cy.type() | 期望页面元素最终处于可以输入的状态 |
cy.click() | 期望页面元素最终处于可以单击的状态 |
cy.its() | 期望能从当前对象最终找到一个属性 |
Cypress断言方法
隐性断言.should()
或者.and()
显性断言expect
expect
允许传入一个特定的对象并且对其进行断言
expect(true).to.be.true
混合使用
BBD形式的断言
命令 | 实例 |
not | expect(name).to.not.equal(‘davieyang’) |
deep | expect(obj).to.deep.equal({name:‘davieyang’}) |
nested | expect({a:{b:[‘x’,‘y’]}}).to.hava.nested.property(‘a.b[1]’) |
nested | expect({a:{b:[‘x’,‘y’]}}).to.nested.include(‘a.b[1]’:‘y’) |
ordered | expect([1,2]).to.hava.ordered.members([1,2]).but.not.hava.ordered.members([2,1]) |
any | expect(arr).to.hava.any.keys(‘name’, ‘age’) |
all | expect(arr).to.hava.all.keys(‘name’, ‘age’) |
a(type)Aliases:an | expect(name).to.not.equal(‘davieyang’) |
include(hava), Aliases:contain, includes, contains | expect([1,2,3]).to.include(2) |
ok | expect(undefined).to.not.be.ok |
TRUE | expect(true).to.be.true |
FALSE | expect(false).to.be.false |
null | expect(null).to.be.null |
undefined | expect(undifined).to.be.undefined |
exist | expect(myVar).to.exist |
empty | expect([]).to.be.empty |
TDD形式的断言
命令 | 实例 |
.isOk(object, [message]) | assert.isOk(‘everything’, ‘everything is ok’) |
.isNotOk(object, [message]) | assert.isNotOk(false, ‘this will pass’) |
.equal(actual, expected, [message]) | assert.equal(3,3,‘vales equal’) |
.notEqual(actual, expected, [message]) | assert.notEqual(3,4, ‘values not equal’) |
.strictEqual(actual, expected, [message]) | assert.notStrictEqual(true, true, ‘bolls strict eq’) |
.notStrictEqual(actual,expected,[message]) | assert.notStrictEqual(5,‘5’,‘not strict eq’) |
.deepEqual(actual, expected, [message]) | assert.deepEqual({id:‘1’},{id:‘1’}) |
.isTrue(value,[message]) | assert.isTrue(true, ‘this value is true’) |
数据驱动策略
将数据保存在前置条件中
利用beforeEach
或者before
前置函数可以把数据保存在前置条件中
使用fixtures
数据保存在自定义文件中
环境变量设置
cypress.env.json
Cypress允许你针对不同测试环境使用多个配置文件并且在运行时动态指定,首先在新建\cypress\config\
路径,并在config
下新建两个json文件,并命名为cypress.dev.json
和cypress.test.json
然后配置/plugins/index.js
文件
实际运行测试时,使用命令yarn cypress run --env configFile=test
指定使用cypress.test.json
环境运行测试
运行时动态指定环境变量
使用cypress.evn.json
可以指定测试环境运行,但需要额外创建文件,除了使用cypress.evn.json
外,在运行时指定测试环境的同时仍然可以使用cypress.json
文件
然后更改/support/index.js
文件
实际执行的时候运行如下命令
yarn cypress:open --env testEnv=test
测试运行最佳实践
静态挑选待运行的测试用例
指的是给测试用例添加关键字,例如describe.only(), describe.skip(), it.only(), it.skip()及给测试用例指定runFlag, 并在运行时指定runFlag的值
详情可查看自动化测试框架[Cypress测试用例]
动态挑选待运行的测试用例
安装插件
npm install --save-dev cypress-select-tests
配置插件
修改cypress/plugins/index.js
文件
测试用例
在integration目录下新建testPickToRun.js
用例执行
实际执行使用命令yarn cypress:open --env grep=e2e
根据文件名来执行用例
执行所有文件名中包含Login
字符的文件
yarn cypress:open --env fgrep=Login
测试运行失败自动重试
安装插件
npm install -D cypress-plugin-retries
配置插件
在cypress/support/index.js
新增配置
require('cypress-plugin-retries')
在package.json
的scripts
代码块中新增配置
执行用例
yarn retryCases
如此所有测试用例执行失败后都会重试2次
Cypress链接DB
Cypress使用cy.task()
来链接DB,语法如下
代码实例
执行task
在/plugins/index.js
中,修改如下代码
然后测试代码便可以如此使用
连接MySQL
安装插件
npm install --save-dev mysql
配置插件
在cypress.json
的evn变量中,配置如下内容
修改/plugins/index.js
文件