速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

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:334522

评论

发布
暂无评论
发现更多内容

2021年抓住金三银四涨薪好时机,腾讯Java社招面试流程

Java 面试 后端

2021我的Java路要怎么走,Java应用性能优化

Java 面试 后端

2021年最新Java面试经历,别再说自己不会了

Java 面试 后端

2021我是如何拿到小米、京东、字节的offer,持久化数据安全RDB、AOF

Java 面试 后端

网络安全必学知识点之XSS漏洞

网络安全学海

黑客 网络安全 信息安全 WEB安全 漏洞挖掘

如何看待游戏世界的未来:解析去中心化区块链游戏的优缺点

CECBC

2021最新京东商城亿级并发架构设计!推荐每一位Java开发者学习

Java 编程 架构 后端 计算机

Flink 实时 metrics

GrowingIO技术专栏

大数据 flink Grafana 流式计算框架

docker 命令备忘(qbit)

qbit

Docker 容器 存储

2021年是意义非凡的一年,2021阿里+头条+腾讯等大厂Java笔试题分享

Java 面试 后端

2021年最新Java大厂面试笔试题分享,Java入门教程免费视频

Java 面试 后端

2021年最新腾讯Java面经,Java面试高级题目

Java 面试 后端

40万奖池 + 顶级云服务资源,云计算大赛系列公开课正式开播

亚马逊云科技 (Amazon Web Services)

人工智能 云计算 创新大赛

2022高频前端面试题汇总之React篇

buchila11

React

2021年春招Java面试题,大厂Java核心面试题出炉

Java 面试 后端

2021年最新Java面试点梳理,阿里P7大牛整理

Java 面试 后端

2021年网易Java岗面试必问,Java开发面试准备

Java 面试 后端

GraphQL 快速入门「3」GraphQL 架构

码语者

Rest GraphSL

解析实现区块链互操作性的方法及现有开发项目

CECBC

QOE 驱动下的分布式实时网络构建:Agora SD-RTN 的演进

声网

Java 人工智能 分布式 网络

2021年这些高频面试知识点最后再发一次,面试官突击一问

Java 面试 后端

2021年阿里Java高级面试题分享,【MySQL

Java 面试 后端

“工业互联 在云之洲”丨“5G+AR”远程协助作业解决方案 赋能装备更智能

云计算,

2021年阿里Java面试题及答案,Java高级进阶学习资料

Java 面试 后端

阿里大佬竟然真的把Java基础核心知识整理成了PDF版

Java 程序员 架构 面试 计算机

百度联手清华大学出版社 打造国内首套产教融合人工智能系列教材

百度大脑

人工智能

2021年阿里Java面试题及答案,多图详解CLH锁的原理与实现

Java 面试 后端

区块链技术的核心、发展与未来

CECBC

2021年腾讯Java高级面试题及答案,百度笔试题百度校招面试经验

Java 面试 后端

说下你可能没用过的EventBus

艾小仙

Centos7 部署 Zabbix 5.4 高可用集群

Se7en

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