本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-07-03
以 cypress open
方式运行 Cypress,是指以交互模式打开 Cypress 测试运行器(Test Runner)运行测试用例,测试用例中的每一条命令,都会显式的显示在Test Runner中,用户可以通过 Test Runner 随时暂停,恢复测试用例执行。
npx cypress open
# 如果 package.json 配置了scripts "cypress:open": "cypress open"
npm run cypress:open
Cypress open 支持的参数有:
–browser, -b: 用来指定待运行的浏览器。 npm run cypress:open --browser chrome
–config, -c:用来指定运行时的配置项。npm run cypress:open --config pageLoadTimeout=100000
–config-file, -C:用来指定运行时的配置文件。npm run cypress:open --config-file tests/cypress-config.json
env, -e:用来指定环境变量。 npm run cypress:open --env host=api.dev.local,version=1,mode=dev
,代码中可以这么访问 Cypress.env('mode')
–global:用来以 global 模式打开 Cypress,global 模式允许在多个嵌套项目中共享同一个安装好的 Cypress 版本。
–port, -p:用来指定运行时的端口。npm run cypress:open --port 8080
–project,-P:如果你的项目包含多个子项目,可以用此参数来运行指定的子项目。npm run cypress:open --project ./some/nested/folder
–help, -h:用来输出 help 信息。
cypress run
命令直接运行测试脚本直至测试结束,Cypress 默认启动无头(Headless)Electron 浏览器来运行测试。
运行的方式与 cypress open
基本一致。支持一下参数,
–ci-build-id:用于分组运行或并行运行,它通过指定一个唯一的标识符来实现,必须配合 –group 或 –parallel 才能使用。npm run cypress:run --ci-build-id BUILD_NUMBER
–group:用来将以此运行中将符合条件的测试用例分组展示。 npm run cypress:run --group smoke --spec 'cypress/integration/somke/**/*'
,通常跟 –ci-build-id 一起使用。
–headed:用来指定有头运行,npm run cypress:run --headed
–no-exit:用来指定 Test Runner 在运行后不退出,可以使用参数 –headed 和 –no-exit 来指定测试运行时显示及在运行后查看命令日志。npm run cypress:run --headed --no-exit
–key, -k:通常跟 Dashboard 一起使用,用来指定那些需要在运行时录制的项目秘钥,将在后续的章节介绍。
–parallel:用来在多台机器上并行运行测试用例集,将在后续的章节介绍。
–record:用来指定在测试运行时录制视频。npm run cypress:run --record --key
,如果你在 cypress.json
配置了环境变量 CYPRESS_RECORD_KEY
则可以忽略 –key 标志。
–reporter, -r:用来指定 Reporter,前文已经介绍过,一起的还有 –reporter-options, -o。具体请查看
–spec, -s:参数用来指定运行哪些测试文件夹/文件。如果你不指定测试文件夹,Cypress将会自动运行所有存在 Integration 文件夹下的测试用例。
–browser 、 –config 、–config-file 、–env 等参数与 cypress open
一致。
测试运行器能够方便用户调试,监控测试运行状态,从而使测试更加便捷。
在你以交互式命令 cypress open
运行测试用例时,你可以在 Test Runner 里指定待测试的浏览器,Cypress 默认使用 Electron 浏览器。
如果测试过程中发生错误,大部分的测试框架都无法得知测试执行时被测应用程序所处的状态,只能在测试运行结束后通过日志、截图来猜测测试失败的原因。Cypress Test Runner 则完全相反,它忠实地记录了每一条测试命令被执行时应用程序所处的状态,并且保存起来以便随时回溯,这种能力被称为时间穿梭。
需要注意的是,Cypress 保存的是应用程序状态,不是截图,故 Cypress 支持查看执行命令时发生的一切操作,用户可直接定位到错误的根本原因,无需猜测。
在测试结束后,可以通过鼠标悬停,或者使用鼠标单击某个命令的方式来进行实践穿梭。
使用鼠标悬停。可以在应用程序预览中查看命令作用到被测应用的具体情况。
使用鼠标单击,将在浏览器的 Console 中看到当命令执行时,应用到了被测应用程序的哪个元素上,以及当时的上下文详细信息。
以下介绍,使用 Cypress 需要注意的地方,与其他测试框架『不太一致』的地方。
describe('测试箭头函数', () => {
beforeEach(function () {
// wrap 'hello' 到 text 中
cy.wrap('hello').as('text');
})
it('访问不到', () => {
// this.text 打印为空
cy.log('hhhhhhhh', this.text)
})
it('访问得到', function () {
// this.text 打印为 hello
cy.log('hhhhhhhh', this.text)
})
})
Cypress 不支持 async 和 await 代码,虽然 Cypress 类似于 Promise 但不同于 Promise,Promise 本身没有重试的概念,但 Cypress 却支持命令自动重试。
同源策略是浏览器安全的基石,这也意味着当两个 iframe 直接有访问时,必须同时满足协议相同、域名相同、端口相同三个条件。由于 Cypress 是运行在浏览器之中的,要测试应用程序,Cypress 必须始终能够和应用程序直接通信。
但显然浏览器的同源策略不允许,Cypress 通过以下方式绕过了浏览器的限制:
首次加载 Cypress 时,内部 Cypress Web 应用程序托管在一个随机端口上,类似 http://localhost:65874/__/
。
在一次测试中,当第一个 cy.visit()
命令被发出后,Cypress 将更改其 URL 以匹配远程应用程序的来源,从而解决同源策略的主要障碍。但这样带来的坏处是,在一次测试中,访问的域名必须处于同一个超域下,否则 Cypress 测试将会报错。
describe('测试同源', () => {
it('立即报错', () => {
// 会立即报错
cy.visit('https://helloqa.com')
cy.visit('https://www.baidu.com')
})
})
在Cypress中,保存一个值或者引用的最好方式是使用闭包,.then()
是 Cypress 对闭包的一个典型应用,.then()
返回的是上一个命令的结果,并将其注入下一个命令中。
// 获取 btn 的值前后进行比较
cy.get('button').then(($btn) => {
const txt = $btn.text();
cy.get('form').submit();
cy.get('button').should(($btn2) => {
expect($btn2.text()).not.to.eq(txt);
})
})
在 Cypress 中,可使用如下方式进行元素赋值操作或者实现比变量共享。
1、.wrap():返回传递给它的对象
const getName = () => {
return 'iTesting';
}
// wrap 返回的对象做了操作使其能够调用 cy 的命令,有点类似于 $()
// const eDiv = document.getElementById('main');
// eDiv.find('input') // Error
// $(eDiv).find('input') // Success
cy.wrap({ name: getName }).invoke('name').should('eq', 'iTesting');
2、.as():用于分配别名以供以后使用,可以使用 cy.get()
和 cy.wait()
加有 @
前缀在别处再次访问,一般与 cy.wrap()/cy.fixture()
配对使用。
decribe('a suite', () => {
beforeEach(() => {
cy.visit('https://www.baidu.com');
cy.contains('更多').then(($el) => {
// 将 '更多' 这个元素的文本存作别名 text
cy.wrap($el.text()).as('more');
})
})
it('测试 alias', () => {
// 在别处访问别名
cy.get('@more').then((val) => {
cy.log(val)
})
})
})
3、fixture()
如果在测试中需要的变量直接来自外部文件,可以通过 fixture()
来实现上下文共享。
.fixture()
用来加载位于文件中的一组固定数据。语法如下:
cy.fixtrue(filePath);
cy.fixtrue(filePath, encoding);
cy.fixtrue(filePath, options);
cy.fixtrue(filePath, encoding, options);
常与 .as()
一起使用:
// user.json 位于 cypress/fixture/ 目录下
cy.fixture('user.json').as('usersData')
cy.get('@usersData').then((data) => {
cy.log(data);
})
4、Cypress.env()
(1)配置 cypress.json
,定义自定义变量用来之后保存运行中生成的变量
{
"env": {
"myCustomVari": "",
"myCustomObj": {}
}
}
(2)在测试中使用 Cypress.env()
来设置和获取变量
describe('', () => {
beforeEach(function () {
cy.visit('/login')
})
it('在前一个测试用例中设置', () => {
cy.contains('In this recipe we').then(($el) => {
Cypress.env('myCustomVari', $el.text())
Cypress.env('myCustomObj').moreTxt = $el.text()
})
})
it('在下一个测试用例中获取', () => {
cy.log('获取设置的变量', Cypress.env('myCustomVari'))
cy.log('获取设置的对象', Cypress.env('myCustomObj'))
})
})