【ArchSummit】如何通过AIOps推动可量化的业务价值增长和效率提升?>>> 了解详情
写点什么

React 单元测试实例:快速上手指南

作者 | Sanjeev Sharma

  • 2023-12-20
    北京
  • 本文字数:3121 字

    阅读完需:约 10 分钟

大小:1.42M时长:08:16
React 单元测试实例:快速上手指南

你是否正计划为你的 React 代码编写测试?是否因找不到好的入门教程而感到苦恼?那么,这篇文章正是你所需要的。在本文中,我们将涵盖编写单元测试的所有步骤以及这个过程中可能遇到的错误和问题。

 

本文使用了JestReact Testing Library库。如果你想使用其他库也没关系,文中的一些基础知识也会对你有所帮助。

 

本文涉及的全部代码都托管在 GitHub 上,文末提供了链接地址。

 

为什么要编写测试

当然,不写测试代码也可以完成产品开发。用户、产品经理,甚至测试人员或 QA 都不在乎该产品是否有测试代码。但是你,作为一名开发人员,应该在乎!

 

假设你有一个拥有数万用户的网站,当你对一个公共的工具函数做了一些重构(或添加了一个功能修复),并在应用中某个调用它的地方进行了测试,表明该函数可以正常运行。于是你选择在周五上线(这是个低级错误)。然后,该函数在应用中的其他地方无法运行,导致网站在周末期间出现线上故障。 此时,你多么希望这些地方能有测试代码,可以在发布生产之前自动运行,从而避免此次故障。

 

上述场景比你想象的还要普遍。你可能还没遇到过(不过,这是迟早的事情),但是包括我在内的很多工程师都已经遇到过了。

 

因此,测试代码之所以很重要,主要有以下几个原因:

 

🚀 增强你对代码发布上线的信心。

📜 测试代码本身也是一种文档。

🛠️ 有助于调试和重构。

⌛️ 从长远来看,有助于减少开发时间。

 

对于所有希望晋升的初级开发人员来说,务必要具备编写测试代码的能力。

 

测试教程


我们将从零开始教你编写测试代码,所以请准备好终端。首先,我们使用 vite 创建一个示例项目。

 


在创建项目后,使用以下命令运行它。

 


程序运行之后,你会在页面上看到一个 demo 应用。

 


我们不会给该应用添加新功能,但为了给按钮编写测试代码,我们需要将按钮重构为一个单独的组件。

 


接下来,我们在页面上添加两个按钮:

 

  1. 一个按钮的功能是点击时将 count 的值乘以 2。

  2. 另外一个按钮的功能是点击时按以下顺序执行操作:如果 count 的值以 0 结尾,那么就将它的值除以 2。如果 count 的值是斐波那契数,那么就将它的值加 1。否则,将 count 的值进行平方操作。

 


我们需要在 utils 模块中声明上面代码中用到的两个函数。同时,我们也声明了一些辅助函数,但由于其他地方并不会用到这些辅助函数,因此这里不需要做导出。

 


代码已经准备好,现在可以开始编写测试代码了。这里我们跳过 React 代码,直接先给工具函数编写测试。这有助于我们了解 Jest 框架的大致用法。

 

下面,让我们为 doubleTheNum 函数编写测试。

 


上面的代码用于测试我们的函数是否可以按预期执行。任何测试代码都会包含以下这些关键组件:

 

  1. describe 函数:第一个参数是字符串,它会在测试运行的时候显示。第二个参数则是测试实际执行的函数。describe 函数的主要作用是对同类型的测试进行分组。这里只有一个测试,在另外一个示例中,你会看到其中有多个测试。

  2. it 函数:其参数结构和 describe 函数类似。但这里的字符串参数应该尽可能详细地描述测试函数的具体内容。当然,你也可以使用 test 函数替代 it。

  3. expect 语句块:此函数中的前三行很简单。其最后一行是通过断言来判断 doubleTheNum 函数能否正确运行。此外,这里我们还用到了 toEqual 匹配器函数。

 

Jest 提供了很多匹配器,例如:

 

  1. toBeNull 用于匹配 null。

  2. toBeTruthy 用于匹配判定结果为 true 的语句。

 

想了解关于匹配器的更多信息,参考如下链接:

https://jestjs.io/docs/using-matchers

 

为了运行测试,我们需要先安装 Jest:

 


然后在 package.json 中添加测试脚本:

 


最后,通过执行 yarn test 命令来运行测试。

 

对于大多数人来说,上面的步骤已经足够了。但如果你遇到了与模块导入或 TypeScript 相关的任何问题,请按以下步骤进行操作:

 

  1. 安装并设置 @babel/preset-env:

 


然后,将它配置到 package.josn 中:

 


  1. 安装 TypeScript 依赖库:

 


然后,在 jest.config.ts 中添加 Jest 配置:

 


然后执行测试,结果如下:

 


从输出中可以看到我们在 describe 和 it 函数中声明的字符串信息。

 

🎉 恭喜,你完成了第一个测试!

 

喜欢这篇文章吗?如果觉得还不错,我推荐你看看我的另一篇最受欢迎的文章《Redux完整指南》,阅读量高达 2.5 万:

https://dev.to/thesanjeevsharma/just-redux-the-complete-guide-44d5

 

接下来,我们给 funkyNum 函数编写测试。

 


编写测试时,应该尽量多地覆盖函数的分支和语句。测试覆盖率越高会让人越有信心。

 

如果你再次运行测试,应该会看到以下输出。

 


理想情况下,我们也应该为 isFibonacci 和 isPerfectSquare 函数编写单独的 describe 语句块。在单元测试中,测试代码应该是互相独立的。简洁起见,这里我们没有这样做。

 

💡小提示

 

  1. 通过调用.skip 或 test.skip 来跳过任何测试,或调用 describe.skip 来跳过整个测试块。

 


  1. 通过调用 it.only 或 test.only 执行单个测试。

 


上面我们已经介绍了如何使用 Jest 进行 JS 代码的测试。现在,让我们深入探讨下关于 React 的测试。

 

在开始之前,我们还需要安装一些依赖库:

 


同时,还需要在 jest.config.ts 中添加环境:

 


下面我们给 CounterButton 组件编写一个最基础的测试:

 


在上面的代码中,我们提供了所需的 props ,并尝试渲染组件。对于任何组件,这都应该是你为它编写的第一个测试。因为如果该测试无法通过,那么其他测试就毫无用处。

 

RTL(React Testing Library)的 render 函数将在 document.body 中渲染传入的组件。

 

它还返回了一些诸如 getByText 这样的查询方法,可用于在 DOM 中查找元素。

 

点击这里查阅所有的查询方法。

 

如果你再次运行测试,应该可以看到 2 组测试——全部为绿色且通过。

 


我们编写的第二个测试是测试组件对于 props 的反应。如果各个 prop 之间没有互相依赖,那么应该为每个 prop 参数都编写单独的测试。

 


getByText 函数是一种查询方法,可以让我们通过字符串来获取元素。

 

toBeInTheDocument 函数是一个和 toEqual 类似的匹配器。Jest 默认不提供该函数,需要在安装 @testing-library/jest-dom 库之后才能使用。

 

不同的环境有不同的包,例如在 React Native 环境中,需要使用 @testing-library/jest-native。

 

如果你再次运行测试,测试应该也会通过。

 

最后,我们来编写本文的最后一个测试,同时也是最重要的一个。我们将编写一个测试来检查点击事件处理程序是否按预期工作。

 

为了生成用户事件(例如点击和按键),我们需要安装另外一个包。

 


与之前的测试代码相比,这次的测试代码几乎一样,只有一些微小的差异。

 


注意:由于是模拟用户事件,所以该函数异步执行。

 

第一行的 jest.fn()是一个模拟函数。在测试运行时,可以通过它跟踪诸如调用参数、调用次数等很多非常有用的信息。类似这样的函数,以后你会看到很多。

 

我们还使用了一种新的查询方法 getByRole 来查找按钮元素。

 

在检查模拟函数是否被调用之前,我们需要先等待点击事件完成。

 

就是这样!如果你运行测试,它们应该也会通过。

 


🔗 这里获取所有代码:

https://github.com/thesanjeevsharma/devto-unit-testing

 

下一步


如果你遵循本文成功地完成了测试代码的编写,那么你可以开始在自己的代码库中添加测试代码并且进一步探索各种测试功能了。

 

另外,我建议你进一步了解以下几个方面的内容:

  1. getByTestId——这是一个使用很普遍的查询方法。当其他方法都不好使的时候,可以用它。

  2. 了解Setup和Teardown方法。它将提升你的测试水平。

  3. 学习如何模拟 npm 模块、API 调用、全局状态和上下文等。

 

原文链接:

https://dev.to/thesanjeevsharma/writing-your-first-unit-test-in-react-150h

 

相关阅读:


React JS 广受业界认可,高级开发者年薪百万

从新 React 文档看未来 Web 的开发趋势

我被 React 劫持了,很痛苦又离不开

React 开发者们的 Solid.js 快速入门教程

2023-12-20 10:334291

评论

发布
暂无评论

详解数据库SQL中的三个语句:DROP、TRUNCATE 、DELETE

华为云开发者联盟

数据库 后端 华为云 华为云GaussDB 华为云开发者联盟

SecureFX for Mac(ftp文件传输工具)

晴雯哥

又一个小而美的涵盖多个实际场景的高并发项目完结了

这我可不懂

软件开发 TDD 测试驱动开发

三策略,六步骤,Jenkins 迁移到极狐GitLab CI 的终极指南

极狐GitLab

ci DevOps gitlab 持续集成 jenkins

AppLink上的小鹅通能实现什么操作呢?

RestCloud

APPlink

交易所开发:加密货币交易平台开发的见解

区块链软件开发推广运营

交易所开发 dapp开发 区块链开发 链游开发 公链开发

IP代理如何助力你的营销业务?如何选择?

Geek_ccdd7f

计算网络之MSTP协议与VRRP协议

不在线第一只蜗牛

计算机网络 计算机知识 协议解析

来听B站音乐UP主从容老师讲解GuitarPro和Earmaster

淋雨

Guitar Pro EarMaster 吉他 声乐 视唱

弹性云主机支持多种规格

天翼云开发者社区

云计算 云主机 云平台

聚焦数据安全,神州数码联合多方发布《数据分类分级自动化建设指南》

科技热闻

情感语音识别技术的发展趋势与前景

来自四九城儿

五个提升SQL语句性能的小窍门,进一步提升查询性能

高端章鱼哥

数据库 sql

专家分享——CAE仿真软件学习心得

智造软件

仿真 CAE 仿真软件 CAE软件 altair

亲身体验云原生顶会北美 KubeCon,5个要点和4个 Fun Facts

小猿姐

Kubernetes 云原生 cncf KubeCON

MatrixOne完成与欧拉、麒麟信安的兼容互认

MatrixOrigin

分布式数据库 云原生数据库 MatrixOrigin MatrixOne HTAP数据库

人工智能 | 开启智慧学习新时代—与AI对话,高效提升学习效率

测吧(北京)科技有限公司

测试

MySQL索引入门

互联网工科生

MySQL 数据库

Live Home 3D Pro for mac(3D家居设计软件) 4.8.3永久激活版

mac

3D家居设计软件 苹果mac Windows软件 Live Home 3D Pro

小程序转换工具—Antmove 使用教学

FN0

小程序 Antmove

软件测试 |人工智能数据生成,ChatGPT引领测试新风潮

测吧(北京)科技有限公司

测试

分布式应用服务的拆分

快乐非自愿限量之名

分布式 开发应用 应用开发

你这些网站都不知道,怎么摸好鱼?

秃头小帅oi

前端 低代码 在线 程序选

避免defer陷阱:拆解延迟语句,掌握正确使用方法

伤感汤姆布利柏

超过5000+企业使用的ETL平台

RestCloud

ETL

Xmind for Mac(思维导图软件) 24.01永久激活版

mac

XMind 思维导图软件 苹果mac Windows软件

云电脑运行原理分析

天翼云开发者社区

虚拟化 云平台 云电脑

持续集成指南:GitHubAction 自动构建+部署AspNetCore项目

EquatorCoco

GitHub 持续集成 集成测试

大数据的技术运用:探索未来的无限可能性

EquatorCoco

大数据 技术应用 城市智能化 医疗健康

有限元分析初学者需要关注哪些问题?

思茂信息

仿真软件 仿真技术 有限元分析 有限元仿真 有限元技术

软件测试 |人工智能引领未来学习趋势——ChatGPT智能学习助手

测吧(北京)科技有限公司

测试

React 单元测试实例:快速上手指南_架构/框架_InfoQ精选文章