cypress 教程
cypress
是一个用于Web
应用程序的端到端测试框架。它是一个开源的js
测试工具,设计的目的是Web
应用程序的测试能更快速、简单和可靠。赛普斯允许开发人员编写模拟用户交互和验证应用程序行为的自动测试。
我们可以使用js
或者ts
来开发,但是js
是cypress
的主要语言。cypress
是建立在js
之上的,使用了许多现代Web
开发的相同概念,比如使用基于浏览器的环境来运行测试,以及使用CSS
选择器与Web
元素进行交互。
在编写cypress
测试时,我们可以使用js
创建模拟用户交互和验证应用程序行为的测试用例。cypress
还提供了一套强大的内置命令和断言,以帮助我们快速和方便地编写测试。
在详细解释cypress
之前,我们先来看看为什么我们要使用cypress
来实现测试用例的自动化。
为什么要使用cypress
通过js编写
cypress
是用js
编写的,对于我们已经熟悉js
的开发人员来说能更容易上手cypress
。
对js框架提供了支持
cypress
对vue
和react
提供了很好的支持。使用这些框架构建应用程序的开发人员可以很容易地为他们的应用程序编写测试。
拥有丰富的与Web应用程序交互的API
提供丰富的与Web
应用程序进行交互的API
,其中包括与DOM
进行交互的方法、HTTP
请求和处理事件。这些API
设计得很容易使用,并且拥有详细的文档介绍,这使得使用js
编写测试变得很容易。
支持 debugger
提供全面的调试体验,包括内置的调试工具和通过测试的能力。
社区支持
有一个庞大的js
开发者社区,意味着大量的资源可以在网上帮助开发者解决他们在使用cypress
时遇到的任何问题。
cypress
使用一个独特的体系结构,使其能够在与被测试的应用程序相同的上下文中运行测试。这意味着cypress
可以访问应用程序的DOM
、网络流量,甚至是后端服务器。这种架构允许更快和更可靠的测试和更直观和强大的测试经验。
使用cypress的好处
cypress
能使编写和运行测试、调试问题变得容易,并确保了Web
应用程序的质量。下面我们将探讨cypress
自动化工具的一些主要特点。
简单的设置
cypress
是非常容易建立和使用。它可以很容易地安装在国家预防机制中,只需要很少的设置。cypress
还配有一个方便用户的图形界面,使开发人员易于导航和使用。
全面 APIS
提供丰富的与Web
应用程序进行交互的API
,其中包括与DOM
进行交互的方法、HTTP
请求和处理事件。这些API
设计得很容易使用,并且拥有详细的文档介绍,这使得使用js
编写测试变得很容易。
实时重载
提供实时的重新加载,这意味着对代码或测试的任何更改都能立即反映在浏览器中。这样可以节省开发人员的时间,使实时查看变化的影响变得容易。
自动等候
在执行下一个命令之前,赛普雷斯JavaSoript会自动等待断言传递和元素显示。这使测试更加稳定,并减少了错误底片的可能性。
调试
配备了内置的调试工具,使故障诊断和修复测试变得容易。开发人员可以使用这些工具来检查DOM
、调试javaSoript代码等。
时间旅行
提供了一个独特的特性,叫做"时间旅行",它允许我们在测试的任何点上来回地检查和调试应用程序。当试图调试复杂的测试场景时,这个功能可以节省开发人员大量的时间和精力。
跨浏览器测试
支持跨浏览器测试,并可以在不同的浏览器上运行测试。这使得我们可以很容易地确保您的应用程序在不同的浏览器中工作。
自动截图和录像
可以自动拍摄测试的截图和视频,这样就可以很容易地看到测试运行过程中发生了什么。这在试图识别应用程序中的问题或错误时会很有帮助。
定制命令
允许开发人员创建自定义命令,这些命令可以在不同的测试中重用。这使得创建一个通用测试命令库和减少代码重复的数量变得容易。
持续整合
可以很容易地集成到流行的连续集成(CI
)工具,如Jenkins
, CircleCI
和Travis CI
.。这使得作为CI/CD
管道的一部分自动运行测试变得容易。
cypress的使用
安装nodejs
需要有nodejs
环境,可以在https://nodejs.org/下载。
创建一个项目
创建一个新目录,并在根目录下通过npm init
来生成package.json
文件
安装 cypress
在根目录下执行
npm install cypress --save-dev
yarn add cypress --dev
打开cypress
npx cypress open
可以看到支持端到端测试和组件测试这两种:
- 端到端测试:从端到端构建和测试应用程序的整个体验,以确保每个流符合我们的期望。
- 组件测试:独立地从设计系统构建和测试组件,以确保每个状态符合我们的期望。
这两种测试存在一定的区别:
端到端测试通过 cy.visit()
访问网站,可以跨多个页面测试流程和功能。而组件测试通过 cy.mount()
导入组件,主要用于隔离测试设计系统的各个组件。
端到端测试生成一个空白规范:
选择浏览器,在这里我们选择Edge
,然后启动端到端测试:
创建一个空白测试用例:
创建完后运行:
在创建了测试用例后,可以在项目根目录上看到多了一个cypress
文件夹,默认文件夹结构如下所示。我们可以在文件夹e2e
下创建测试用例。
cypress的项目结构
-
cypress
:这是cypress
项目的主文件夹(也就是执行run cypress open
命令后生成的)。它包含与我们的测试相关的所有子文件夹和文件。
-
e2e
:这是存储所有测试的主文件夹。我们可以在此处添加基本、端到端测试。所有的spec
文件都在这个文件夹里边。 -
fixtures
:这个文件夹可以用于存储测试中使用到的静态数据文件,例如JSON
或CSV
文件。例如,包含多个测试用例可以使用的测试数据列表。 -
support
: 此文件夹包含可在多个测试文件之间共享的可重用测试代码。可以包括自定义命令、页面对象或函数。
support
文件夹中有两个文件:commands.js
和 index.js
。
-
command.js
:用于放置常用函数和自定义命令。包括在不同测试文件中使用到的常用函数。Cypress
为也我们创建了一些函数,如果有特殊需求,也可以在此处重写它们。 -
e2e.js
:这个文件在每个测试文件之前运行。在此文件中,我们保留所有全局配置,并可以根据需要进行修改。默认情况下,它仅导入commands.js
,但是我们也可以导入或要求其他文件。 -
node_modules
:所有节点包将安装在node_modules
目录中,并在所有测试文件中可用。简而言之,这是NPM
安装所有项目依赖项的文件夹。 -
cypress.config.js
:这是cypress
框架使用的配置文件,用于自定义框架和测试的行为。该文件可用于配置测试的各种设置,例如应用程序的基本URL
、视口大小、测试超时值和其他选项。
除了上述文件夹外,我们还有一些文件夹,例如“屏幕截图”、“下载”和“视频”来存储不同的相关文件。
cypress 的基本结构
cypress
使用与 Mocha
相同的语法来编写测试用例:
-
describe()
: 该方法用于对相关测试用例进行分组。它需要两个参数:一个描述测试用例组的字符串和一个包含各个测试用例的回调函数。 -
it()
: 该方法用于定义测试用例。它需要两个参数:一个描述测试用例的字符串和一个包含实际测试代码的回调函数。一个describe()
至少要包含一条测试用例:it()
. -
before()
:此方法用于在特定描述的块中的任何测试用例之前运行设置函数。可用于设置测试环境、初始化变量以及执行其他设置任务。 -
after()
: 此方法用于在特定描述的块中的所有测试用例完成运行后运行清理功能。它可用于清理测试环境、关闭打开的连接以及执行其他清理任务。 -
beforeEach()
: 此方法用于在特定描述的块中的每个测试用例之前运行设置函数。它可用于重置测试环境的状态并执行其他设置任务。 -
afterEach()
: 此方法用于在特定描述的块中的每个测试用例完成运行后运行清理功能。它可用于重置测试环境的状态并执行其他清理任务。 -
.skip()
: 当处理大型代码库并希望专注于特定测试或测试子集时,.skip()
函数提供了一种方便的方法来暂时阻止某些测试的执行。
测试应用下载
我们使用Cypress.io的官方提供的测试应用来做介绍,就不单独写应用了。
在github上复制项目
git clone git@github.com:cypress-io/cypress-example-recipes.git
之后在根目录下安装依赖:
npm install
所有应用例子都在项目的examples
文件夹下。
启动测试应用
进入想要测试的应用的目录。
我们这里以登录应用为例(logging-in__xhr-web-forms
目录).
进入该应用的目录:
cd examples\logging-in__xhr-web-forms
启动服务:
npm start
启动成功后,cmd
窗口将显示服务器的地址和端口
在浏览器中访问:
进行 UI 测试
cypress
提供对应用程序 DOM
的轻松访问,从而可以轻松操作和断言页面上各个元素的状态。它还支持插件,可用于扩展其功能并与其他工具和服务集成。这些是 cypress
成为 UI
测试首选的原因。
测试用例
在之前创建的空白测试文件中进行修改:
describe('login', () => {
const username = 'jane.lane';
const password = 'password123';
it('login ', () => {
cy.visit('http://localhost:7079/login');
cy.get('input[name=username]').type(username);
cy.get('input[name=password]').type(password);
cy.get('form').submit();
cy.url().should('include', '/dashboard');
cy.get('h1').should('contain', 'jane.lane');
});
});
进行 API 测试
可以创建将 HTTP
请求发送到其应用程序的 API
并验证相应响应的测试。
这种类型的测试对于测试 API
响应、验证数据输入和输出以及验证应用程序的行为特别有用。它还提供了几个内置断言,可用于验证响应状态代码、标头和正文。
以下是使用 Cypress
进行 API
测试的一些关键功能:
HTTP
请求cypress
提供了简单直观的API
来发出HTTP
请求,允许开发人员轻松测试不同的API
端点和参数。它支持所有常见的HTTP
方法,例如GET
,POST
,PUT
,DELETE
等。mock
cypress
允许您模拟API
响应,这在测试依赖于第三方服务或数据源的 API 端点时非常有用,这些服务或数据源在开发/测试期间可能不可用。- 请求和响应对象
cypress
提供请求和响应对象,允许开发人员检查和操作API
发送和接收的数据。这有助于测试具有嵌套数据结构的复杂API
。 - 身份验证和授权
cypress
支持测试需要身份验证或授权的API
。测试人员可以使用内置的cy.request
方法来发送身份验证令牌或cookie
,也可以使用插件与外部服务(如OAuth
提供程序)集成。 - 内置对
GraphQL
的支持 cypress
为测试GraphQL API
提供了内置支持,包括简化GraphQL
查询的GraphQL
请求方法。
测试用例
GET请求
GET
方法用于检索特定数据,并在从 API
响应读取代码时传递参数。
describe('login', () => {
it('is redirected using cy.request', function () {
cy.request({
url: 'http://localhost:7077/dashboard',
followRedirect: false,
}).then((resp) => {
expect(resp.status).to.eq(302);
expect(resp.redirectedToUrl).to.eq('http://localhost:7077/unauthorized');
});
});
});
POST请求
在 POST
请求中,我们通过在body
中传递数据。
describe('login', () => {
const username = 'jane.lane';
const password = 'password123';
it('test login', function () {
cy.request({
method: 'POST',
url: 'http://localhost:7077/login',
form: true,
body: {
username,
password,
},
});
cy.getCookie('cypress-session-cookie').should('exist');
});
});
其他请求方式类似,就不一一列举了。
进行组件测试
组件测试的目的是验证各个软件模块(如函数、类或方法)的功能和行为,以确保它们按预期工作并满足设计中指定的要求。
组件测试的主要目的是在软件模块集成到更广泛的系统之前发现软件模块中的缺陷或故障,从而最大限度地减少下游故障的可能性,并简化隔离和解决问题的过程。
通过隔离测试每个组件,开发人员可以确信每个模块都正常工作,这可以提高整体系统质量并减少测试和调试的时间和成本。
测试用例
这里以react
为例:
# 创建一个项目:
create-react-app my-new-sample-app
# 在项目中安装cypress
npm i cypress -D
# 打开cypress
npx cypress open
之后选择组件测试
选择react
框架
安装所有依赖项:
之后的流程跟之前提到的一样,选择浏览器跟创建空白测试规范。
最终创建的文件夹:
在 src
文件夹中创建一个“计数器组件”,并命名为 lambadaTest.jsx。
import { useState } from 'react'
export default function Counter({ initial = 0 }) {
const [count, setCount] = useState(initial)
return (
<div style={{
padding: 30
}}>
<button style={{ color: "black", backgroundColor: "green", margin: 10 }} aria-label="decrement" onClick={() => setCount(count - 1)}>
-
</button>
<span data-cy="counter">{count}</span>
<button style={{ color: "black", backgroundColor: "green", margin: 10 }} aria-label="increment" onClick={() => setCount(count + 1)}>
+
</button>
</div>
)
}
执行下面的命令来运行测试用例:
npx cypress open --component
可以看到组件测试已执行
编写用例:
- 单击 (+) 以增加计数。
- 单击 (-) 以递减计数。
import Counter from '../../src/lambadaTest'
describe("<Counter>", () => {
const counterSelector = '[data-cy="counter"]';
const incrementSelector = "[aria-label=increment]";
const decrementSelector = "[aria-label=decrement]";
it("Do two time increment then one time decrement the count ", () => {
cy.mount(<Counter />);
// 增加两次
cy.get(incrementSelector).click();
cy.get(incrementSelector).click();
cy.get(counterSelector).should("contain.text", 2);
// 递减
cy.get(decrementSelector).click();
cy.get(counterSelector).should("have.text", "1");
cy.get(decrementSelector)
.should("have.css", "color")
.and("eq", "rgb(0, 0, 0)");
cy.get(decrementSelector)
.should("have.css", "background-color")
.and("eq", "rgb(0, 128, 0)");
});
it("Do two time decrement then one time increment the count ", () => {
cy.mount(<Counter />);
cy.get(decrementSelector).click();
cy.get(decrementSelector).click();
cy.get(counterSelector).should("have.text", "-2");
cy.get(incrementSelector).click();
cy.get(counterSelector).should("have.text", "-1");
cy.get(decrementSelector)
.should("have.css", "color")
.and("eq", "rgb(0, 0, 0)");
cy.get(decrementSelector)
.should("have.css", "background-color")
.and("eq", "rgb(0, 128, 0)");
});
});
将计数递增两次,然后递减一次计数。
将计数递减两次,然后递增一次计数。