前言
提示:为什么要学cypress?
一、简介
Cypress是即end to end(端到端)功能测试框架,它基于node.js。开箱即用,不仅支持本地浏览器直接模拟测试,也支持终端测试。还有测试录屏功能,方便在测试失败的时候,查看当时的失败的场景,方便定位。
Mocha 适用于 Node.js 和浏览器的测试框架,它使得异步测试变得简单
Chai 断言库
简化了设置测试、编写测试、运行测试和调试测试,支持端到端测试、集成测试和单元测试,支持测试在浏览器中运行的任意内容。支持 Mac OS、Linux 和 Windows 平台
二、原理
Webdriver 运行的方式
大多数测试工具(如:Selenium/webdriver)通过在外部浏览器运行并在网络上执行远程命令来运行
因为 Webdriver 底层通信协议基于 JSON Wire Protocol,运行需要网络通信
Cypress 运行的方式
Cypress 和 Webdriver 方式完全相反,它与应用程序在相同的生命周期里执行
三、特性
时间穿梭【历史记录】
Cypress 在测试代码运行时会自动拍照
等测试运行结束后,用户可在 Cypress 提供的 Test Runner 里,通过悬停在命令上的方式查看运行时每一步都发生了什么
实时重新加载
当测试代码修改保存后,Cypress 会自动加载改动地方,并重新运行测试
Spies(间谍)、Stubs(存根)、Clock(时钟)
Cypress 允许你验证并控制函数行为,Mock 服务器的响应,更改系统时间
单元测试触手可及!
运行结果一致性
Cypress 架构不使用 Selenium 或 Webdriver,在运行速度、可靠性测试、测试结果一致性上均有良好保障
可调试性
当测试失败时,可以直接从开发者工具(F12 Chrome DevTools)进行调试,这熟悉吧??
自动等待
使用Cypress,永远无须在测试中添加 强制等待、隐性等待、显性等待
Cypress 会自动等待元素至可靠操作状态时才执行命令或断言
异步操作触手可及!
网络流量控制
Cypress 可以 Mock 服务器返回的结果,无须依赖后端服务器,即可实现模拟网络请求
截图和视频
Cypress 在测试运行失败时会自动截图,在无头运行时(无GUI界面)会录制整个测试套件的视频
四、优势
像我们在用 Selenium 时,需要集成单元测试框架(unittest、pytest),想要好看的测试报告还得集成(allure),想要 Mock 还得引入对应的 Mock 库
而 Cypress 是开箱即用!啥意思?看下图!
五、安装使用
1. npm install cypress --save-dev # 安装cypress
运行 node_modules/.bin/cypress open
1.1 在项目根目录下增加配置文件cypress.json
1.2 在 package.json 文件添加对应启动脚本:
1.3 “Cypress不能选择Chrome浏览器”的解决方法
1.查看Chrome浏览器所在文件位置
2.将Chrome下的Application文件夹拷贝至
C:\Program Files (x86)\Google\Chrome
3. 进入Application文件夹选择chrome.exe,启动Chrome,启动成功。
4.启动cypress,确认是否可选Chrome浏览器,发现可以选择了。
1.4 目录结构
cypress_demo
├── cypress # Cypress 工作目录
│ ├── fixtures # 测试用例中要用到的资源,比如:数据库模拟数据、图片、json信息等等,可以使用fixture方法读取
│ │ └── example.json
│ ├── integration # Cypress 脚本测试文件,允许多级目录
│ │ └── examples # 这个文件夹中存放了 Cypress 官方提供的一些测试样例
│ │ ├── actions.spec.js
│ ├── plugins # 存放 Cypress 插件
│ │ └── index.js
│ └── support # 存放 Cypress 自定义命令
│ ├── commands.js
│ └── index.js
├── cypress.json # Cypress 配置文件
└── package.json # 这个要自己创建
2. 直接下载Cypress压缩包
① 官网下载地址:https://download.cypress.io
② 解压到指定目录,然后进入目录,执行Cypress.exe
新建一个测试文件 Cypress\integration\example
六、流程
流程-映射到Cypress对应的命令上
七、命令
1.选择器
1.1 Cypress专有选择器
data-cy
data-test
data-testid
1.2.其它选择器
A.#id选择器通过html元素id属性来获取DMO获取用户名input元素方法:
cy.get('#account').click()
B.class类选择器
类选择器通过html元素class属性来获取DMO获取用户名input元素方法:
cy.get('.form-control').click()
C.attributes属性选择器
类选择器通过html元素class属性来获取DMO获取用户名input元素方法:
cy.get('[input[id = "account"]]').click()
D.nth-child(n)选择器
:nth-child(n)选择器匹配属于其父元素的第n个子元素,不论元素的类型。获取用户名DOM元素方法:
cy.get(tbody > tr:nth-child(1) > th')
2. 获取dom元素基本方式
.find(selector) 搜索定位元素
.get(selector) 搜索定位元素
.contains(selector) 搜索定位元素
.children() 方法用来获取DON元素的子元素
.parents() 用来获取DOM元素的所有父元素
.parent() 用来获取DOM元素第一层元素
.siblings() 用来获取DOM元素的所有同级元素
.first() 用来获取指定DOM对象的第一个元素
.last() 用来获取指定DOM对象的最后一个元素
.next() 用来匹配DOM对象紧跟着的下一个同级元素
.nextAll() 用来匹配给定的DOM对象的所有同级元素
.nextUntil() 用来匹配给定DOM对象之后的所有同级元素直到遇到Until里定义的元素为止
.prev() 用来匹配给定DOM对象紧跟着的上一个同级元素
.prevAll() 用来匹配给定的DOM对象之前的所有同级元素
.prevUntil() 用来匹配给定DOM对象之后的所有同级元素直到遇到Until里定义的元素为止
.each() 用来遍历数组及其类似结果
.eq() 用来在元素或者数组中的特定索引处获取DOM元素。类似于Jquery中nth:child()
cy.get('ul>li').each(($item, $index) => {
if ($index !== 0) {
values.push(text);
cy.log($index.toString());
cy.log(text);
}
})
cy.get('li').eq(0).click()
3. 操作事件
4. 断言
4.1. BDD断言
.should
should('have.class', 'success') 断言元素的class属性值是 'success'
should('have.text', 'Column content') 断言元素文本值 'Column content'
should('contain', 'Column content') 断言元素文本包含 'Column content'
should('have.html', 'Column content') 断言元素html文本'Column content'
should('match', 'td') chai-jquery 使用 "is()"检查元素是否与选择器匹配
.invoke('text').should('match', /column content/i) 文本与正则表达式匹配先使用invoke结合should
.contains('text') 文本与正则表达式匹配元素文本包含,这种比上面更好
.and()
针对同一元素多个断言,可以使用 and 语法
cy.get('.assertions-link') .should('have.class', 'active') .and('have.attr', 'href') .and('include', 'cypress.io')
expect
针对项目 BDD 断言方式
expect(true).to.be.true
4.2.TDD断言
5. 数据请求
八、基本使用
1.编写简单的测试用例
context('第一个测试', () => {
before(function () {
//初始化执行所有用例之前运行,执行一次
cy.log("我是before")
})
after(function () {
//初始化执行所有用例完之后运行,执行一次
cy.log("我是after")
})
beforeEach(function () {
//每条用例执行之前都执行
cy.log("我是beforeEach")
cy.visit('')
})
afterEach(function () {
// 每条用例执行之后都执行
cy.log("我是afterEach")
})
})
2.自动完成测试用例和录制
npm run cypress:run