工具 – 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 ...
随机推荐
- Peaks:每周至少要进行一次用户访谈?
名字:Peaks 开发者 / 团队:Vogelhaus Apps GmbH 平台:iOS.watchOS 请简要介绍下这款产品 每个人生活的节奏都有一个内置的生理时钟,这就是所谓的昼夜节律.它不仅控制 ...
- QAnything AI开源的企业级本地知识库问答解决方案,致力于支持任意格式文件或数据库的问答
QAnything AI简介 QAnything ai是一个本地知识库问答系统,旨在支持多种文件格式和数据库,允许离线安装和使用.您可以简单地删除任何格式的任何本地存储文件,并获得准确.快速和可靠的答 ...
- 顺序表_C
// Code file created by C Code Develop #include "ccd.h" #include "stdio.h" #incl ...
- JAVA Spring Boot快速开始
实践环境 Spring Boot 3.2.1 Maven 3.8.8 JDK 1.8.0_331 创建项目 通过http://start.spring.io/网站创建包含Spring Boot的项目, ...
- 图书《数据资产管理核心技术与应用》核心章节节选-3.1.2. 从Spark 执行计划中获取数据血缘
本文节选自清华大学出版社出版的图书<数据资产管理核心技术与应用>,作者为张永清等著. 从Spark 执行计划中获取数据血缘 因为数据处理任务会涉及到数据的转换和处理,所以从数据任务中解析血 ...
- 【VMware】将NAT虚拟机开放访问
NAT模式下面需要将主机内的虚拟机提供给外部访问 这个设置可以通过开启端口来实现外部访问NAT虚拟机 主机端口 - 映射 虚拟机 IP 的端口,问题是有多少个虚拟机应用就需要开多少个端口...
- 很好用的python游戏环境:强化学习算法走迷宫游戏环境(导航问题 navigation):分享一个python语言的迷宫游戏环境
项目的GitHub地址(作者:莫凡): https://github.com/MorvanZhou/mmaze 运行的示例代码: import mmaze start = (0, 0) end = ( ...
- MindSpore1.3.0 GPU pip方式安装 —— Ubuntu18.04系统 (最终安装结果为成功)需要管理员权限,sudo安装
官网地址: https://www.mindspore.cn/install =========================================================== 安 ...
- Python语言中当前工作目录(Current Working Directory, cwd)与模块搜索第一路径都是指什么???
相关: 查看并添加python中库的搜索路径 [python]自问自答:python -m参数? ( python3.7 版本 ) 本文主要解释Python语言中的两个基本概念: 当前工作目录(Cur ...
- 哈希基础知识学习-python版
哈希 哈希表 根据key直接进行访问的无序数据结构,复杂度为O(1) 哈希表的实现---字典 初始化 d1 = dict() 查找 #使用中括号[]进行查找,括号内为特定的键, 键-值 dic = { ...