持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
背景
- 为了绕过同源策略,当 Cypress 开始运行测试时,会在 localhost 上打开一个随机端口进行初始化
- 直到遇见第一个 cy.visit() 命令里的 URL 才匹配被测应用程序的 URL
当 Cypress 以交互模式启动时,会看到 Cypress 先运行在 localhost 上然后又切换到 URL 重新运行(多消耗了一部分时间)
设置全局 URL
做法
在 cypress.json 中设置 baseUrl
优势
- 可以在运行时节省 Cypress 匹配被测应用程序 URl 的时间
- 还可以在编写待访问的 URL 时,忽略 baseUrl,直接写后面的路径
小栗子
// 不加 baseUrl 的写法
cy.visit('https://example.cypress.io/commands/actions')
// 加了上面 baseUrl 的写法
cy.visit('/commands/actions')
背景
- 为了绕开同源策略的限制而实现的方案,使得 Cypress 不能支持在一个测试用例文件里访问多个不同域名的 URL
- 如果访问了多个不同域名的站点,Cypress 会直接报错
避免访问多个站点
访问相同超域
如果访问的是同一个超域下的不同子域,则 Cypress 允许你正常访问
it('访问同一超域下的不同子域', function () {
cy.visit('https://example.cypress.io')
cy.visit('https://www.cypress.io/features')
});
测试结果
访问不同超域
it('访问不同超域,会报错', function () {
cy.visit('https://example.cypress.io')
cy.visit('https://www.cnblogs.com/poloyy/')
});
测试结果
背景
- 在其他的自动化测试框架中,很大概率会用到强制等待(sleep),隐式等待
- 但在 Cypress 中,你无须使用等待,Cypress 的许多命令都自带自动重试机制
删除等待代码
it('错误哦做法,强制等待的栗子', function () {
cy.server()
cy.route('/commands/action/*').as('getAction')
cy.wait(3000)
cy.log(123)
});
it('正确的做法,使用别名来等待', function () {
cy.server()
cy.route('/commands/action/*').as('getAction')
cy.wait('@getAction', {timeout: 50000}).then(function (xhr) {
cy.log(xhr)
})
});
背景
- 在测试运行时截图和录屏能够在测试错误时快速定位到问题所在
- Cypress 截图和录屏功能强大
无须配置,自动截图
以 cypress run 方式运行测试时,当测试发生错误时,Cypress 会自动截图,并默认保存在 cypress/screenshots 文件夹下,而录屏会保存在 cypress/video 文件夹下
命令行运行结果
console 会看到错误截图和录屏的生成路径
生成截图和录屏的目录
自定义截图,.screenshot() 方法
作用
截取被测应用程序的屏幕快照,以及 Cypress 命令日志的屏幕快照
语法格式
.screenshot()
.screenshot(fileName)
.screenshot(options)
.screenshot(fileName, options)
// ---or---
cy.screenshot()
cy.screenshot(fileName)
cy.screenshot(options)
cy.screenshot(fileName, options)
fileName
- 待保存图片的名称
- 图片默认保存在 cypress/screenshots 文件夹下,可以在 cypress.json 修改默认文件夹路径(配置项 screenshotsFolder )
options 详解
通过 onBeforeScreenshot、onAfterScreenshot,可以在截图发生前或发生后应用自定义的行为
正确用法
// 直接截图整个页面
cy.screenshot()
// 只截图某个特定元素
cy.get('.post').screenshot()
命令返回结果
返回上一条命令相同的结果
.screenshot() 栗子
测试代码
it('简单的栗子', function () {
// 截图整个页面
cy.screenshot()
});
测试结果
为什么截图这么长呢?
因为 capture 默认值就是 fullpage,代表整个页面
.screenshot(filename) 栗子
测试代码
it('文件名', function () {
cy.screenshot('文件名')
});
测试结果
.screenshot(options) 栗子
capture:viewport 的栗子
测试代码
cy.screenshot({
capture: 'viewport'
})
测试结果
capture:runner 的栗子
测试代码
cy.screenshot({
capture: 'runner'
})
测试结果
.screenshot() 命令日志
可以看到各配置项(options)的默认值
onBeforeScreenshot 的栗子
截图某个元素
测试代码
测试结果
$el 是当前元素
截图结果
截图整个页面
测试代码
测试结果
$el 是页面根标签
onAfterScreenshot 的栗子
截图某个元素
测试代码
测试结果
可以看到 props 是当前的一些属性,后面有需要可以获取对应的属性值(格式:props.path)
onAfterScreenshot 源码
可以看到不同属性的数据类型