工具 – Cypress
介绍
Cypress 是一款 e2e 测试工具。每当我们写好一个组件或者一个页面之后,我们会想对整体做一个测试。
在不使用工具的情况下,我们会开启 browser,然后做一系列点击、滚动、填 form 等等交互,然后观察看看是否全部运行正常,这就是 e2e 测试。
而借助 Cypress,我们可以把这套测试流程写成代码封装起来。让它变成自动化测试。若以后代码修改了,我们就不需要人工测试(费劲)。
参考
YouTube – Cypress in a Nutshell
Cypress 环境
Cypress 的环境是独立于我们程序的。我们甚至可以用 Cypress 测试别人的程序,比如测试 google.com。
Cypress 基于 Node.js,只要 Node.js 就可以了,不需要 Webpack、Vite 之类的。
当然我们也可以把 Cypress 和我们的程序放到一块。它们也不冲突。
Get Started
create project
创建一个项目。这里我用 Vite TypeScript。你可以用其它的,Cypress 只要有 Node.js 就可以了。
写一个简单的页面
.html


<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head> <body>
<form autocomplete="off">
<input name="firstName" placeholder="First Name" required>
<input name="lastName" placeholder="Last Name">
<button>Submit</button>
<p class="thank-you">Thank you! We have received your enquiry.</p>
</form>
<script type="module" src="./home.ts"></script>
</body> </html>
.scss


@use '../module/reset'; body {
height: 100vh;
display: flex;
justify-content: center;
align-items: center; form {
min-width: 320px; display: flex;
flex-direction: column;
gap: 16px; input {
border-radius: 4px;
border: 1px solid black;
padding: 16px;
} button {
border-radius: 4px;
background-color: pink;
color: red;
padding: 20px;
font-size: 20px;
text-transform: uppercase;
letter-spacing: 1px;
} .thank-you {
line-height: 1.5; &:not(.shown) {
display: none;
}
}
}
}
.ts


import './home.scss'; document.querySelector('form')!.addEventListener('submit', e => {
e.preventDefault();
document.querySelector('.thank-you')!.classList.add('shown');
});
运行
yarn run vite
效果
install cypress
yarn add cypress --dev
添加 cypress 到 tsconfig.json
"compilerOptions": {
"types": [
"cypress"
]
},
如果是 vite 的话,inclde 也需要添加 cypress folder
运行
yarn run cypress open
它会打开一个 App
进入 E2E Testing。
for 第一次,它会创建一些 folder and file
folder and file
选一个 browser 做测试
创建第一个 test file
文件的位置
write test
describe('test form', () => {
it('common use', () => {
cy.visit('https://192.168.1.152:4200/src/home/home.html'); // 访问我们的程序页面
cy.get('.thank-you').should('not.be.visible'); // 检查 thank you message 必须是 hidden
cy.get('input[name="firstName"]').type('Derrick'); // 查找 input firstName 输入 'Derrick'
cy.get('input[name="lastName"]').type('Yam');
cy.get('button').click(); // 点击 submit
cy.get('.thank-you').should('be.visible'); // 检查 thank you message 必须是 shown
});
});
Cypress 的测试代码一般上都是 UI 操作。然后检查 UI 的变化。当然它也可以发 request 检查资料是否输入到 database 等等。
反正人怎么 test 它就怎么 test 就对了啦。
测试结果
它会一行一行跑,去操作 UI。并且检查 UI display 是否正确。
注: Cypress 的 event 都是模拟的,比如 click 它是通过 JavaScript 触发的。有一个插件 cypress-real-events 可以实现 real click 和 keyboard tab。
常用招数
base URL
去 cypress.config.ts 加上 baseUrl
import { defineConfig } from 'cypress'; export default defineConfig({
e2e: {
baseUrl: 'https://192.168.1.152:4200',
},
});
测试文件就不需要写长长的 path 了
it('common use', () => {
cy.visit('https://192.168.1.152:44200/src/module-e2e-test/form/accessor/accessor.html'); // before
cy.visit('/src/module-e2e-test/form/accessor/accessor.html'); // after
});
specPattern
Cypress 默认测试文件的路径时 cypress/e2e/**/*.cy.{js,jsx,ts,tsx}
有时候我们更希望把 .cy.ts 和测试页面放到一块
可以这样配置
export default defineConfig({
e2e: {
specPattern: [
'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
'src/module-e2e-test/**/*.cy.{js,jsx,ts,tsx}',
],
},
});
长这样
expect + equal & deep.equal
熟悉单元测试的人对 expect 应该很熟悉了。Cypress 也是有这些冬冬,不过语法和 Jasmine 有些出入。
eq、equal、equals
expect(1).eq(1); // true
expect('Hello').equals('Hello'); // true
expect({}).equal({}); // false
expect(NaN).equal(NaN); // false
expect(0).equal(-0); // true
expect(null).equal(undefined); // false
equal 有多个别名,上面三个方法其实都是等价的。
equal 是 ===,不是 Object.is 哦。
deep.equal
expect({ name: 'Derrick' }).deep.equal({ name: 'Derrick' }); // true
expect({ name: 'Derrick' }).eqls({ name: 'Derrick' }); // true
expect({ name: 'Derrick' }).eql({ name: 'Derrick' }); // true
deep.equal 是比较正规的写法,另外 2 个是 alias,尽量不要用,它容易和 equal 混淆。
cy.log
想 debug Cypress 可以使用 cy.log
cy.visit('/src/module-e2e-test/form/accessor/accessor.html');
cy.log('debug...');
效果
query element and doing something / check with element
输入字到 input
cy.get('input').type('value');
check 是否可见
cy.get('.card').should('be.visible');
cy.get('.card').should('not.be.visible');
select parent and then select child
// 下面这样是错误的
const form = cy.get('.grandparent .parent .child form');
form.find('input[type="firstName"]').type('value');
form.find('input[type="lastName"]').type('value'); // 下面这样才是正确的,我也不清楚为什么,懒得去查
const formSelector = '.grandparent .parent .child form ';
cy.get(formSelector + 'input[type="firstName"]').type('value');
cy.get(formSelector + 'input[type="lastName"]').type('value');
delay on page load
有时候 page load 需要等一下才操作,不然容易报错。
before(() => cy.visit('/').wait(1000));
检查 after window.open,更复杂的可以参考这篇 Stack Overflow – Access a new window - cypress.io
cy.window().should('have.length', 2);
each & wrap
当 get multiple element 时可以用 each 遍历,each 之后可以用 cy.wrap 把 $el 变成 Cypress element,这样就可以操作了。
cy.get('.pricing-section-component .pricing .service-cta-component').each($el => {
$el.addClass('dada'); // $el is jQuery element
const nativeElement = $el.get(0); // get native element
cy.wrap($el).click(); // wrap become cypress elemenet
});
native element
Cypress select element 用的是 jQuery,想拿到 native element 需要多一个 step
cy.get<HTMLInputElement>('input[name="text"]').then($input => {
cy.log($input.get(0).validationMessage); // Please fill out this field.
});
.then + $input.get(0) = native element
它也经常搭配 .should + expect 使用
cy.get<HTMLInputElement>('input[name="text"]').should($input => {
expect($input.get(0).validationMessage).equal('Please fill out this field.');
});
Vitest(Jasmine) 和 Cypress(Mocha) 的语法区别
Vitest 是 beforeAll,Cypress 是 before
Vitest 是 toBe, Cypress 是 equal (而且前者是 Object.is,后者是 ===)
Cypress tsconfig
当程序和测试都在一个项目里时,可能 tsconfig 不一致,那么可以通过上面这个方法来做 override。
目前有一个 Bug – TypeScript 5 support for sourceMap option 我们必须得这么做才行。
工具 – Cypress的更多相关文章
- nodejs新工具-cypress和testcofe的崛起
今天咨询一个自动化 工具问题,偶然间有人提起了这个可能以后会很火的工具,在此找到一篇很好的参考文章 记录并为以后做准备 cypress和testcofe https://www.jianshu.com ...
- 前端开发:基于cypress的自动化实践
作为一个伪开发,在一个平台项目中负责前端的开发工作,开发框架为vue,本文我会站在前端开发的角度介绍,我是如何使用cypress的. [x] 如何在vue中使用cypress [x] 如何运行cypr ...
- Cypress测试工具
参考博客: https://testerhome.com/articles/19035 最近一段时间学习了cypress的测试工具, 她是一个端到端的测试web工具. 环境准备 1.工具:vs co ...
- E2E测试工具之--01 Cypress 上手使用
The web has evolved. Finally, testing has too. 1. 简介 cypress 最近很火的e2e(即end to end(端到端))测试框架,它基于node ...
- [原创]FPGA JTAG工具设计(一)
先来看不同JTAG方案,下载配置QSPI Flash所耗时间 基于FTDI方案,JTAG下载时间为494sec JTAG chain configuration ------------------- ...
- 2018.5.28 PSOC第一枪:基于cypress的蓝牙开发
Cypress-BLE 开发套件可以快速开发 物联网电子产品. PSOC编程特点: A 拖放各PSoC 组件到工作区中,以设计原理图B 完成各组件之间的布线,并配置GPIOC 使用所包含的组件API ...
- 后Selenium时代,网页自动化测试用Cypress
本文技术难度★★★,初学自动化测试的朋友慎点!否则会引起焦虑等不适症状,严重者会怀疑自己技术人生! 来自Cypress官网首页! Web开发飞速换代! table控制页面OUT了! 原生态手写网页OU ...
- CYPRESS最新的USB3.0控制器
CYPRESS近日发布了其最新的USB3.0控制器,产品序号为CX3,主要是针对高像素摄像头方面的应用,接口支持MIPI的CSI-2,并不支持传统的基于并口的数据传输模式. MIPI(Mobile I ...
- Cypress安装使用(E2E测试框架)
一.简介 Cypress是为现代网络打造的下一代前端测试工具,解决了开发人员和QA工程师在测试现代应用程序时面临的关键难点问题. Cypress包含免费的.开源的.可本地安装的Test Runner ...
- Cypress自动化环境搭建
1.Cypress 下载: 官网下载,下载后直接解压即可,解压后便可单机exe文件打开 Ps:直接打开exe是会报错找不到json文件的,所以还要安装依赖环境 运行cypress项目前,必须vue-c ...
随机推荐
- 算法金 | 来了,pandas 2.0
大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今日 210+/10000,内含 Pandas 是一个强大的数据分析库,广泛应用于科学 ...
- 构筑开放式大数据架构,Apache Kyuubi和NDH荣登开源OSCAR
[点击了解更多网易大数据技术] 在9月16日召开的"2022 OSCAR开源产业大会"上,中国信息通信研究院发布了一系列开源研究成果和开源表彰,网易数帆发起的开源项目Apache ...
- 痞子衡嵌入式:瑞萨RA8系列高性能MCU开发初体验
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是瑞萨RA8系列高性能MCU开发上手体验. 我们知道瑞萨半导体的通用 MCU 产品线主要包含基于自有内核 8/16bit RL78 系列以 ...
- linux mysql 允许进行远程连接 比如 navicat
出于安全方面考虑默认只允许本机(localhost, 127.0.0.1)来连接访问.所以开启远程访问权限.登录mysqlmysql -uroot -pxxxxxx 1:GRANT ALL PRIVI ...
- Django集成的密码找回功能
要实现忘记密码功能,您需要进行以下修改: 添加忘记密码链接到登录页面. 创建密码丢失修改页面. 创建密码修改页面. 编写相应的视图函数来处理密码丢失修改和密码修改逻辑. 编写发送验证信息到邮箱的逻辑. ...
- oeasy教您玩转vim - 60- # vim选项
vim选项 从头开始 这次我们从头开始 从进入vim之前开始 我们可以在终端里面给vim怎么样的参数呢? man vim 这个如果不行的话 要先运行unminimize更新manual 也可以在v ...
- ceph 001 存储类型 传统存储与分布式存储 分布式文件系统 集群与分布式
ceph 存储类型 块存储:裸磁盘 未被格式化的磁盘 DAS(直连存储,usb,硬盘插到电脑):scsi接口 接口数量有限 传输距离有限 SAN(存储区域网络):ip-san 网络(iscsi) 以太 ...
- pip升级导致报错:pip消失
pip升级导致报错:pip消失 在安装Jupyter Notebook的时候需要用首先更新pip,如下: 使用以下命令更新pip和安装Jupyter pip3 install --upgrade pi ...
- 【Java】Generic 泛型
Generic 泛型 为什么需要泛型? 集合容器再设计阶段/声明阶段不能确定这个容器实际存储的是什么类型的对象 JDK5 以前只能把元素设计为Object基类 在JDK5之后用泛型来约束对象类型 除了 ...
- 【Uni-APP】02 FLEX 弹性布局
新建一个项目: 注释所有内容: <template> <!-- <view class="content"> <image class=&quo ...