介绍

Cypress 是一款 e2e 测试工具。每当我们写好一个组件或者一个页面之后,我们会想对整体做一个测试。

在不使用工具的情况下,我们会开启 browser,然后做一系列点击、滚动、填 form 等等交互,然后观察看看是否全部运行正常,这就是 e2e 测试。

而借助 Cypress,我们可以把这套测试流程写成代码封装起来。让它变成自动化测试。若以后代码修改了,我们就不需要人工测试(费劲)。

参考

YouTube – Cypress in a Nutshell

Docs – Get Started

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

常用招数

参考: Docs – Using Cypress FAQ

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的更多相关文章

  1. nodejs新工具-cypress和testcofe的崛起

    今天咨询一个自动化 工具问题,偶然间有人提起了这个可能以后会很火的工具,在此找到一篇很好的参考文章 记录并为以后做准备 cypress和testcofe https://www.jianshu.com ...

  2. 前端开发:基于cypress的自动化实践

    作为一个伪开发,在一个平台项目中负责前端的开发工作,开发框架为vue,本文我会站在前端开发的角度介绍,我是如何使用cypress的. [x] 如何在vue中使用cypress [x] 如何运行cypr ...

  3. Cypress测试工具

    参考博客:  https://testerhome.com/articles/19035 最近一段时间学习了cypress的测试工具, 她是一个端到端的测试web工具. 环境准备 1.工具:vs co ...

  4. E2E测试工具之--01 Cypress 上手使用

    The web has evolved. Finally, testing has too. 1. 简介 cypress 最近很火的e2e(即end to end(端到端))测试框架,它基于node ...

  5. [原创]FPGA JTAG工具设计(一)

    先来看不同JTAG方案,下载配置QSPI Flash所耗时间 基于FTDI方案,JTAG下载时间为494sec JTAG chain configuration ------------------- ...

  6. 2018.5.28 PSOC第一枪:基于cypress的蓝牙开发

    Cypress-BLE 开发套件可以快速开发 物联网电子产品. PSOC编程特点: A 拖放各PSoC 组件到工作区中,以设计原理图B 完成各组件之间的布线,并配置GPIOC 使用所包含的组件API ...

  7. 后Selenium时代,网页自动化测试用Cypress

    本文技术难度★★★,初学自动化测试的朋友慎点!否则会引起焦虑等不适症状,严重者会怀疑自己技术人生! 来自Cypress官网首页! Web开发飞速换代! table控制页面OUT了! 原生态手写网页OU ...

  8. CYPRESS最新的USB3.0控制器

    CYPRESS近日发布了其最新的USB3.0控制器,产品序号为CX3,主要是针对高像素摄像头方面的应用,接口支持MIPI的CSI-2,并不支持传统的基于并口的数据传输模式. MIPI(Mobile I ...

  9. Cypress安装使用(E2E测试框架)

    一.简介 Cypress是为现代网络打造的下一代前端测试工具,解决了开发人员和QA工程师在测试现代应用程序时面临的关键难点问题. Cypress包含免费的.开源的.可本地安装的Test Runner  ...

  10. Cypress自动化环境搭建

    1.Cypress 下载: 官网下载,下载后直接解压即可,解压后便可单机exe文件打开 Ps:直接打开exe是会报错找不到json文件的,所以还要安装依赖环境 运行cypress项目前,必须vue-c ...

随机推荐

  1. [oeasy]python0091_仙童公司_八叛逆_intel_8080_altair8800_牛郎星

    编码进化 个人电脑 计算机 通过电话网络 进行连接 极客 利用技术 做一些有趣的尝试 极客文化 是 认真研究技术的 文化 计算机 不再是 高校和研究机构高墙里面的 神秘事物 而是 生活中常见的 家用电 ...

  2. AT_arc111_a 题解

    洛谷连接&Atcoder 链接 题目简述 给定两个数 \(n\) 和 \(m\),输出 \(\left\lfloor\frac{10^n}{m}\right\rfloor \bmod m\) ...

  3. Linux 基于flock命令实现多进程并发读写文件控制

    基于flock命令实现多进程并发读写文件控制 需求描述 实际项目中,需要在Linux下通过shell脚本并发读写同一个文件,但是希望同一时刻,只有一个进程可以在读.写目标文件. 解决方案 使用floc ...

  4. application.properties配置文件存储参数

    配置文件存储参数 当我们需要很多的参数时,项目很大,文件很多,每涉及一个技术,每涉及一个第三方的参数时,当这些参数数据发生变化,修改会相当的麻烦.这时候把参数配置到application.proper ...

  5. 强化学习入门书籍《DeepReinforcementLearningHands-On-SecondEdition》

    前段时间在网上买了本强化学习入门的书籍,即<Deep-Reinforcement-Learning-Hands-On>,虽然是影印版的,但是感觉还是可以看看的,说的也蛮易懂的,感觉比现在市 ...

  6. python报错:Pip 20.3+ break proxy connection

    参考: https://www.cnblogs.com/devilmaycry812839668/p/17872452.html =================================== ...

  7. ubuntu系统下 vscode中如何指定conda环境

    参考: https://blog.csdn.net/mieleizhi0522/article/details/89336321 =================================== ...

  8. aarch64/arm_v8 环境下编译Arcade-Learning-Environment —— ale-py —— gym[atari]的安装

    aarch64架构下不支持gym[atari]安装,因此我们只能在该环境下安装gym,对于atari环境的支持则需要源码上重新编译,也就是本文给出的下面的方法: 源码下载: https://githu ...

  9. MPI在Deep Learning的主流时代背景下除了传统计算领域外对DL的应用前景如何,MPI与NCCL的区别在哪???

    做分布式计算的基本上10年之前只听说过MPI,14年之前只听过hadoop的MapReduce,17年之前只听过TensorFlow. 那么这三个分布式计算软件或者说框架有什么区别呢???现在都是搞d ...

  10. 关于python的GIL的解除——PEP 703 – Making the Global Interpreter Lock Optional in CPython

    PEP地址: https://peps.python.org/pep-0703/ PEP 703 – Making the Global Interpreter Lock Optional in CP ...