React 中的单元测试

2025年3月17日 | 阅读 10 分钟

单元测试是一种测试方法,它在隔离的过程中测试单个软件单元。检查给定输入下的函数的输出。

这意味着验证组件是否能够对 React 组件的任何特定道具进行渲染。

换句话说,编写单元测试就像编写验证代码是否按预期工作的代码一样。

单元测试、集成测试和端到端测试之间有什么区别?

单元测试测试尽可能小的代码单元,以及组件可能存在的任何依赖项。

集成测试测试*多个*组件协同工作的情况。这些测试提供了对用户体验应用的最佳理解。

测试的缺点是,找出导致测试失败的组件会更加复杂。虽然单元测试失败时会指出特定组件存在问题,但集成测试失败可能由许多组件引起,而并非明确指出了导致失败的组件。

端到端测试称为用户界面测试,它通过从用户角度测试整个系统来接管集成测试。

测试无法了解系统,它从用户的角度关注系统。

测试通过应用程序运行,并验证用户界面是否与预期结果匹配,这是手动和自动化测试的结果。

最直接的方法是查看测试金字塔来解释将协同工作的测试。

Unit Testing in React

单元测试是金字塔的底部,因为它被认为是为测试打下基础。它更容易编写,并且最适合编写代码和修复错误。

单元测试的目的是什么?

单元测试有很多有用的原因。其中一些如下:

  • 它会运行您的代码。
  • 它能防止回归。
  • 开发中更快的反馈。

这些都是有效的观点,但编写单元测试的主要优点是*提高编码风格*。

在实现功能期间或之前编写测试,可以让我们更好地了解需求。编写松耦合且易于测试的代码。最初是通过重构代码片段来使其更易于测试。

例如,我们将函数提取到单独的文件中,以便代码更容易测试。之后,结果是耦合度降低了。

单元测试的主要意图

它在几次场合中阻止我们将 bug 发送到生产环境。

单元测试在所有方面都帮助我们。它们是有充分理由构成任何可靠测试套件的基础。

何时应该编写单元测试?

关于何时编写单元测试,存在很多意见。我们可以通过测试驱动开发 (TDD) 来编写,TDD 告诉我们在编写代码之前编写测试用例,而有些人则倾向于在代码编写完成后编写单元测试。

单元测试的最大优势在于,当您在实际部署期间编写测试时,这并不意味着我们必须遵循该建议。

在以下情况下编写测试用例是最好的主意:

  • 在新功能实现期间或之前。
  • 重构之前和期间。
  • 修正错误之前。

我们需要哪些工具来开始 React 的单元测试?

现在我们知道了单元测试是什么,让我们开始编写第一个测试。让我们看看将用于编写自动化测试的工具。

要开始编写 React 的单元测试,您只需要以下两种类型的工具。

  • 测试运行器
  • 测试实用程序

为 React 选择测试运行器

什么是测试运行器?

测试运行器是一个程序,它运行测试(在单元测试的情况下)并让我们识别测试何时通过或失败。

  • 它是通过自动化单元测试执行来消除摩擦的关键工具。它允许将单元测试作为 CI 管道(持续集成)的一部分。
  • 它消除了摩擦,这将使开发人员更容易运行测试。

测试涉及状态的组件

请注意,有两种测试集可以测试我们的类组件。

  • 行为性。 我们可以模拟点击按钮,并看到按钮的文本已更改。我们正在观察用户的行为并测试预期的更改。
  • 基于组件。 它测试组件的切换方法,并查看它是否按我们预期的那样工作。当切换函数更复杂,并且我们想测试单元测试的不同场景时,这很有用。

两者的结合使我们获得了更高的信心。

React 单元测试的先决条件

我们使用两个重要的库,名为 **Jest** 和 **Enzyme** 来进行单元测试。Jest 是一个非常流行的库,由 Facebook 编写,并且在一段时间内变得流行(您也可以使用 mocha 或 chai 等其他库来代替 Jest)。

Jest 帮助我们进行所有断言,而 Enzyme 帮助我们在测试模式下渲染 React 组件。我们将在下面详细介绍它们。

让我们看看用于测试 React 应用的广泛使用的工具。

Jest

在 React 中,最常用的测试运行器是 Jest。我们可以在监视模式下运行 Jest,它可以运行我们的测试,每次我们保存文件时。

Jest 是一个运行我们所有测试套件和测试用例的测试运行器。Jest 已在测试 JavaScript 和 React 应用程序中之前介绍过。我们必须从命令行调用 Jest 来运行测试用例。我们可以对 Jest 进行额外的自定义设置配置。

安装

Jest 提供了一个配置文件来提及额外的配置。我们在包中提供文件路径,JSON 文件如下。

让我们在根文件夹中创建一个 jest.config.json 文件,并在 package.json 文件中添加脚本来运行我们的测试。

让我们在根文件夹中创建一个 jest.config.json 文件,并在 package.json 文件中添加脚本来运行我们的测试。

Enzyme

Enzyme 于 2015 年 12 月问世。它是 React 的一个补充,简化了 React 组件的输出测试。

Enzyme 是一个与 Jest 在许多测试库中一起使用的库,它用于渲染组件和遍历 DOM。

如果我们构建 React 应用,Jest 和 Enzyme 是测试 React 应用的最佳组合。

Jest 是一个主要用于执行带断言的测试用例的测试运行器。同时,Enzyme 是一个与 Jest 库一起使用的库,它提供了 React 组件的渲染技术(如 shallow、mount 等),并遍历 DOM 的渲染输出。

让我们看看 Enzyme 的设置。

安装

Enzymes 提供适配器来处理多个版本的 React。所以,在 React 中安装适配器。接下来,我们下面安装 React16。

现在,您必须在适配器中配置 Enzyme 来在 prank 测试环境中安装。

让我们创建 jest.setup.js 并在文件中添加以下代码。

您已经安装了 Enzyme 在您的环境中。

决定测试需要什么以及应该排除什么非常重要。

这样,考虑到您之后的任何人来管理这些测试用例,就不会留下大量不必要的测试和快照文件。

对于每个要进行单元测试的组件,从小型无状态组件开始,然后转向更复杂的组件。这样,如果任何复杂的 React 组件包含另一个已经过测试的较小组件,这将使过程更容易。

然而,在*测试驱动开发 (TDD)* 过程中,您应该首先决定并编写最初会失败的测试用例,然后逐步开发能够通过测试的测试用例的功能。

考虑一个小的例子来理解。

1.

2.

一个 Display Name 组件,它接收一个 Name 属性作为 props 并将其渲染出来。

文本输入中的 User 组件作为 Name 属性,验证用户名,并在找到错误时设置错误。

我们导出了两个组件和验证函数,供我们进一步测试使用。

对上述示例进行单元测试

有两种主要方法可以测试 React 组件。

  • 快照测试
  • 逻辑/功能测试

1. 快照测试

快照测试会在当前状态下生成组件的快照,并在运行测试时将其存储在名为“**__snapshots__**”的文件夹中。

所以,下次我们更改组件或修改它时,重新运行测试;

如果失败,将拍摄新快照,该快照清楚地显示了组件输出提供的快照之间的差异。如果测试失败,我们可以接受或拒绝更改并相应地修改组件。

如何进行快照测试?

以前,我们需要安装 **react-test-renderer 实用程序**来在测试中渲染组件。

让我们通过在名为 UserName.spec.js 的文件中编写以下测试用例来尝试第一个快照。

以前,我们渲染了 displayName 组件,将其转换为 JSON,并检查它是否与之前的快照匹配。让我们通过 cmd 中的“**npm run test**”命令运行测试,看看结果。

第一次运行测试时,它会生成组件输出的快照并将其存储在“**__snapshots__**”文件夹中。我们来看看它存储的结构。

现在,替换 Display Name 组件并再次运行测试。


Unit Testing in React

我们可以看到它显示了组件中的更改,并且测试失败,因为它无法匹配上一个快照。

这是一个实现更改以修复它的方法。您需要更新快照,它表示组件中存在一个 bug 并且需要修复。我们可以使用“-u”选项通过更新快照来修复它。

同样,我们也为父组件添加了一个快照测试。

2. 逻辑/功能测试

我们可以添加一些测试用例和更多的测试到我们的代码中,以测试验证函数。

我们在这里添加了两个测试用例。

  • 它检查当用户输入任何数量的姓名输入时是否会发送错误消息。
  • 它检查当 name 属性的输入框为空时,错误消息是否与 false 匹配。

所以,它涵盖了应用程序在开发时我们可能忘记处理的逻辑中可能出现崩溃的各种情况。

现在,如果我们运行测试,我们可以看到下面给出的输出。

Unit Testing in React

如果验证失败,正在运行的测试将通知您;所有测试都将通过。将逻辑分开在处理复杂代码的可能情况下非常有帮助,并且看起来是一种更清晰的理解代码的方式。

Reaction 测试库

与 Enzyme 不同,react-testing-library 侧重于用户行为而不是实现。

重点是通过使用 react 测试库来检查一组 props 的正确输出,该库通过 Enzyme 为组件编写端到端测试。

如果您不确定要测试什么,请测试您期望组件渲染的内容。

测试此组件的所有不同状态。如果您期望根据传入的 props 渲染不同的内容,请使用不同的 props 渲染外部组件并进行相应的断言。

例如,当您单击或悬停按钮时,测试会发生某些事情。

如果您提供了一个自定义按钮组件,并将 color prop 的值设置为 red,那么您可以对其进行测试,它会让您确信该组件符合设计要求。

结论

编写单元测试非常重要,这是最简单的测试类型,可以提高项目信心和代码的正确性。我们必须争取更高的代码覆盖率,使其成为编写单元测试用例工作流程的一部分。


下一个主题React 中的轮播