每个开发人员都希望发布一个没有错误的生产应用程序。 为了实现这一点,我们需要考虑如何将测试集成到我们的应用程序中。 我们可以使用许多测试工具、框架和测试类型。

Cypress 是一个现代化的自动化测试套件。 它是一个基于 JavaScript 的完全开源的测试框架,由 Mocha 和 Chai 等支持 BDD 和 TDD 断言样式的库构建。 此外,如果您熟悉用 JavaScript 编写测试,那么使用 Cypress 会很容易。

Cypress 涵盖了两种主要的编写测试风格:端到端测试和单元测试。 在本文中,我们将使用 Cypress 进行单元测试。 我们将概述单元测试,讨论使用赛普拉斯的好处、赛普拉斯的安装、命令和断言,运行赛普拉斯,并编写我们的测试。

  • 什么是单元测试?

  • 使用 Cypress 进行测试的好处

  • 安装赛普拉斯

  • 赛普拉斯断言中的命令

  • 在我们的应用程序中运行 Cypress

  • 设置我们的示例组件

  • 在 Cypress 中编写单元测试

什么是单元测试?

开发人员使用单元测试来验证应用程序是否运行良好。 它涉及独立检查应用程序的每个模块。

术语“单元”是指应用程序的单个可测试部分。 此过程可帮助测试人员和开发人员捕捉和理解开发环境中的早期错误。 然后,工作人员有足够的时间来更改任何缺陷代码。

不同类型的测试之间出现混淆的情况并不少见。 下表涵盖了端到端测试和单元测试之间的主要区别:

端到端 (E2E) 测试 单元测试
用于从头到尾测试整个应用程序。 用于测试应用程序的各个单元。
检查应用程序的行为流。 检查单元的功能验证。
通常是一种昂贵的测试手段。 通常是一种具有成本效益的测试方法。
主要是手动执行。 大部分是自动化的。
测试应用程序的端到端部分。 模块单独测试。

由于赛普拉斯涵盖了前面提到的两个测试领域,因此它一直是我们今天构建的现代应用程序的绝佳测试选择。 让我们看看赛普拉斯如何帮助我们构建更好的可测试产品。

使用 Cypress 进行测试的好处

总的来说,这些是我迄今为止发现的使用 Cypress 进行测试的最大好处:

  • 时间旅行调试

  • 实时代码重新加载

  • 当前和以前的状态差异

  • 运行无头测试或在浏览器中测试之间的选择

  • 能够截取测试的屏幕截图和视频记录

  • 异步测试

  • 浏览器内调试环境

赛普拉斯测试会拍摄快照,并且可以提供可读的错误和堆栈跟踪,以便于调试。 我们也不需要在测试中添加睡眠超时事件,因为它具有自动等待功能,可确保测试在继续之前等待命令和断言。

我发现赛普拉斯的测试比传统的测试套件更简单,而且速度更快。 Cypress 支持并行执行、导入外部库、操作对象、存根 API 调用和网络流量控制,并且 有很棒的学习文档 。

超过 20 万开发人员使用 LogRocket 来创造更好的数字体验 了解更多 →

此外,赛普拉斯可以测试我们应用程序的每一层,包括 UI、数据库、API、前端存储、跨浏览器功能、XHR 请求等。

安装赛普拉斯

Cypress 在 Node.js 服务器上运行,该服务器经常与浏览器(测试运行器)通信,由 Cypress 工具化。 它同时运行两个 iFrame,其中一个是我们的测试代码。 另一个是查看实际测试的 iFrame。

我们将使用以下命令从头开始创建一个 React 和 Vite 项目:

npm create vite@latest

在我们的应用程序中,让我们通过运行以下命令将 Cypress 添加到我们的开发依赖项中:

npm i cypress --save-dev

请确保您选择了我们可用的单元测试选项。 有了这个,我们将生成几个文件夹:

├── cypress
│   ├── downloads
│   └── component
│   └── fixtures
│   └── support
├── cypress.config.js

downloads当我们想要使用正在执行的测试的屏幕截图或视频记录时,它会派上用场。

component是我们将要编写单元测试的位置。 我们将创建稍后可以在 iFrame 中选择的新文件。

fixtures将加载我们需要测试的所有 JSON 数据。

support是我们可以添加自定义命令的地方。 我们可以稍后导入它们并在我们的测试中使用它们。

cypress.config.js是我们可以从赛普拉斯配置中动态修改配置值和环境变量的地方。

来自 LogRocket 的更多精彩文章:

  • 不要错过 The Replay 来自 LogRocket 的精选时事通讯

  • 了解 LogRocket 的 Galileo 如何消除噪音以主动解决应用程序中的问题

  • 使用 React 的 useEffect 优化应用程序的性能

  • 之间切换 在多个 Node 版本

  • 了解如何 使用 AnimXYZ 为您的 React 应用程序制作动画

  • 探索 Tauri ,一个用于构建二进制文件的新框架

  • 比较 NestJS 与 Express.js

执行测试后,赛普拉斯会自动关闭浏览器。 我们不需要明确地关闭浏览器窗口。

可以在我的 GitHub 链接上找到完整的工作代码存储 库 。

Cypress 中的命令和断言

命令和断言是 Cypress 中的重要概念,因此在继续之前让我们回顾一下它们。

首先,我们有命令。 赛普拉斯提供了一个 API 和方法来与应用程序的 UI 进行交互。 我们可用的命令将具有一个内置方法,我们可以在测试块中调用该方法。 本质上,我们可以模拟用户尝试执行用于创建断言的操作。

在下面的示例代码段中,我们使用 get获取元素的命令。 然后我们使用 should并传递了一个链式断言来断言我们期望从测试中得到的东西。

it('sample testing ', () => {
 cy.visit('/')
 cy.get('#name').type('Elon Musk')
 cy.get('#password').type('programming-rocks')
 cy.get('#submit').click()
 cy.get('.messages--error').should('be.visible').and('contain', 'Unrecognized username or password. Forgot your password?')

断言是我们测试块的检查点,用于确认自动化测试是通过还是失败。 Cypress 捆绑了 Chai、 jQuery 和 Sinon.JS 库用于断言。 他们检查运行测试的期望的、预期的应用程序。 可以在 此处的文档 中找到完整的断言列表。

在我们的应用程序中运行 Cypress

如果我们可以从命令行界面 (CLI) 打开 Cypress,那将非常方便。 我们可以! 为此,我们可以添加:

 "scripts": {
   "cypress": "cypress open"

这将允许我们打开一个默认的 Cypress iFrame,我们可以在其中选择要执行的测试文件。 我们可以使用命令运行它 npm run cypress.

设置我们的示例组件

现在,我们将开始测试我们创建的一个简单的电影列表组件。 当我们单击按钮时,它会接收电影的名称并将其添加到我们的 UI 中。 我们还可以单击电影列表并将其标记为已观看,以及关闭所有已观看的电影。

import { useState } from 'react';
function Movielist() {
 const [userInput, setUserInput] = useState('');
 const [movieList, setMovieList] = useState('');
 const handleChange = (e) => {...}
 const handleSubmit = (e) => {...}
 const handleClick = (e) => {...}
 const handleSeen = (e) => {...}
 return (
   <div className="wrapper">
     <form onSubmit={handleSubmit}>
       <input value={userInput} type="text" onChange={handleChange} placeholder="Movie wishlist" />
       <button>+Add movies</button>
     </form>
     <div className="movieList">
       {!movieList && <span data-cy='empty' className="empty">No movies here</span>}
       <ul data-cy='movie-list'>
         {movieList && movieList.map(m => {
           return (
             <li onClick={handleClick} className={m.seen ? "strike movie-list" : "movie-list"} id={m.id} key={m.id}>
                 {m.movie}
               </span>
     {movieList.length > 0 && <><button data-cy='clear-movie' className="outline-btn" onClick={handleSeen}>Clear seen movies</button></>}
export default Movielist

有了这个组件,我们就可以开始单独测试这个组件了。

秒看电视App,高质量电视直播TV,高清频道秒播无卡顿!

在 Cypress 中编写单元测试

在我们的里面 component文件夹,我们将创建一个名为 Movielist.cy.js. 这将包含一个简单的测试执行,它访问我们在本地运行的应用程序。

import Movielist from '../../src/components/Movielist';
describe('<Movielist>', () => {
 it('Mount the component', () => {
   cy.mount(<Movielist />);

以上 import支持声明,我们还可以从 Cypress 包中为每个支持的框架安装函数。 如果我们运行命令 npm run cypress,我们应该看到我们的组件已准备好在浏览器中进行测试。

describe('<Movielist>', () => {
 it('Component mounts', () => {
   cy.mount(<Movielist />);
 it('Component mounts', () => {
   cy.mount(<Movielist />);
   cy.get('[data-cy=empty]').contains('No movies here');

我们需要将我们的组件安装在每个 it()我们为测试创建的块。 为此,我们可以利用 beforeEach()提供给我们的方法。 这看起来更干净,更容易:

describe('<Movielist>', () => {
 beforeEach(() => {
   cy.mount(<Movielist />);
 it('Check no movies', () => {
   cy.get('[data-cy=empty]').contains('No movies here');

这绝对看起来比以前更好。 现在,我们将继续并添加一个测试来检查我们是否可以使电影愿望清单工作。

describe('<Movielist>', () => {
 beforeEach(() => {
   cy.mount(<Movielist />);
 it('The List of movies appends', () => {
   cy.get('[data-cy=empty]').contains('No movies here');
   const formInput = cy.get('form input');
   formInput.should('have.value', '');
   formInput.type('Monster Inc.')
     .should('have.value', 'Monster Inc.');
   cy.get('form button').click();
   formInput.clear();
   formInput.type('Circle of eight')
     .should('have.value', 'Circle of eight');
   cy.get('form button').click();
   cy.get('[data-cy=movie-list]').children().should('have.length', 2);

到目前为止,我们已经通过了我们编写的所有测试,并检查了我们是否已经实现了组件的预期行为。

现在,我们将测试附加到该组件的最后一个功能,该功能使用“ 清除电影” 按钮关闭已观看的电影。 这听起来和我们之前写的很像,让我们看看它是什么样子的:

 it('uncheck movie', () => {
   const lastListitem = cy.get('[data-cy=movie-list]:nth-child(1) li:last-child');
   lastListitem.click();
   lastListitem.should('have.class', 'strike');
   cy.get('[data-cy=clear-movie]').click();
   cy.get('[data-cy=movie-list]').children().should('have.length', 1);
   cy.get('[data-cy=clear-movie]').click();
   cy.get('[data-cy=movie-list]').children().should('have.length', 1);

我们检查了是否可以将电影标记为已观看,然后在电影名称中添加一个删除线。 我们清除了看过的电影,并在界面中测试了我们可用的电影数量。 我们还测试了我们编写的组件。

拥有充足的代码测试覆盖率总是更好。 您可能已经注意到,它看起来就像在 Cypress UI 测试中的真实点击交互和模拟。 这也是使用赛普拉斯的主要好处之一:可见界面、时间旅行等等。

要快得多 测试我们的应用程序组件比进行端到端测试 。 我们的组件测试与在基于节点的运行器(如 Jest 和 Mocha)中执行的组件测试类似。

我们终于得到它了! 我们已经成功地使用 Cypress 为我们应用程序的单个组件编写了单元测试。 我们现在可以向我们的用户交付完全工作的、无错误的代码。

Cypress 与语言无关,因此您可以将其与任何其他编程语言一起使用,而不仅仅是 JavaScript。 有了这个,我们实现了完全自动化的测试,解决了传统测试工具的痛点。 Cypress 是前端开发人员和测试自动化工程师编写自动化 Web 测试的绝佳选择。

中了解更多关于 Cypress 的信息 你可以在他们的官方文档 。 它们是了解更多关于赛普拉斯及其使用方法的绝佳资源。

全面了解生产 React 应用程序

调试 React 应用程序可能很困难,尤其是当用户遇到难以重现的问题时。 如果您对监控和跟踪 Redux 状态、自动显示 JavaScript 错误以及跟踪缓慢的网络请求和组件加载时间感兴趣,请 尝试 LogRocket 。

LogRocket 就像一个用于 Web 和移动应用程序的 DVR,几乎可以记录您的 React 应用程序上发生的所有事情。 无需猜测问题发生的原因,您可以汇总并报告问题发生时应用程序所处的状态。 LogRocket 还监控您的应用程序的性能,并使用客户端 CPU 负载、客户端内存使用情况等指标进行报告。

LogRocket Redux 中间件包为您的用户会话增加了一层额外的可见性。 LogRocket 记录来自 Redux 存储的所有操作和状态。

开发人员使用单元测试来验证应用程序是否运行良好。它涉及独立检查应用程序的每个模块。术语“单元”是指应用程序的单个可测试部分。此过程可帮助测试人员和开发人员捕捉和理解开发环境中的早期错误。然后,工作人员有足够的时间来更改任何缺陷代码。不同类型的测试之间出现混淆的情况并不少见。端到端 (E2E) 测试单元测试用于从头到尾测试整个应用程序。用于测试应用程序的各个单元。检查应用程序的行为流。检查单元的功能验证。通常是一种昂贵的测试手段。通常是一种具有成本效益的测试方法。主要是手动执行。 一个现代的客户端单页应用程序(SPA),用于调度采访,它使用React和Storybook构建,并使用Jest,Testing-Library和Cypress进行了全面测试。 随附于Express和PostgreSQLNode中内置的 。 该应用程序的主要功能是允许学生预订和管理导师的面试。 由于SPA的特性以及使用简单的指示器在发生异步操作时通知用户,因此用户体验非常流畅,无需刷新页面。 状态客户端通过与Express服务器和PostgreSQL数据库通信的API进行同步并与服务器保持一致。 完整功能清单 有关功能的完整列表,请检查此应用程序的列表。 在交互式监视模式下启动测试运行器。 有关更多信息,请参见关于的部分。 npm run build 构建生产到应用程序build文件夹。 它在生产模式下正确捆绑了React,并优化了构建以获得最佳性能。 生成被最小化,并且文件名包括哈希值。 您的应用已准备好进行部署! 有关更多信息,请参见关于的部分。 npm run eject 注意:这是单向操作。 eject ,您将无法返回! 如果您对构建工具和配置选择不满意,则可以随时eject 。 此命令将从您的项目中删除单个生成依赖项。 相反,它将所有配置文件和传递依赖项(we
初识Cypress Cypress (https://www.cypress.io/)是一款功能强大的端到端的Web 测试框架。相比于其他类似最大的特点就是有个可视化的UI界面,调试起来相当直观方便。使用的时候要按业务需要写一些测试用例就可以用带界面或者纯命令行模式来跑了。 Cypress依赖于node js 环境,估计做web 开发的人都是有的。Cypress本身可以用npm安装在目标项目下: npm install cypress --save-dev 或者用yarn 也行   为了保障软件质量,并减少重复性的测试工作,自动化测试已经被广泛运用。   自动化测试是一种测试方法,是指使用特定的软件,去控制测试流程,并比较实际结果与预期结果之间的差异。通过将测试自动化,可以把人对软件的测试行为转化为由机器自动执行测试的行为,从而替代大量的手工测试操作,使得测试可以快速,反复的进行。   关于自动化测试,有一个测试金字塔模型,该模型把测试从下到上分为了单元测试、集成测试和UI自动化测试(E2E测试/UI界面测试)。越往金字