最近和小伙伴们在尝试做把项目中经常用到的 React 组件整理成一套 React 组件库。为了保证代码质量且方便日后维护,我们决定为组件编写单元测试。接下来几篇文章会聊聊在这个过程中我们遇到的问题以及一些思考。

正文开始

要写单元测试,首先面临的一个问题就是“我该使用哪个测试框架”?

如果你去 Google 上搜索“how to test react component”,在结果页面中你大概会来来回回看到以下几个名词/概念:

首先让我们来看看这些库的功能和定位,然后再来做选择。

🃏 Jest

Jest 是 Facebook 开发的一款 JavaScript 测试框架。在 Facebook 内部广泛用来测试各种 JavaScript 代码。其官网上主要列出了以下几个特点:

虽然 Jest 官网介绍中多次 React,但实际上 Jest 并不是和 React 绑定的。你可以使用它测试任何 JavaScript 项目。

Enzyme

由 Airbnb 出品。官方文档中给自己的定义是:

Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components’ output.

从这里可以看出两点信息:

  1. Enzyme 的定位是一个工具库
  2. Enzyme 的出现是为了让我们更方便遍历、操作 React 组件输出的内容

Mocha

Mocha 是另一个 JavaScript 测试框架。与 Jest 不同的是,它自身只提供作为一个测试框架最核心的功能。而其它增强功能,如丰富的断言语法、mock、测试覆盖率统计等功能则是通过各种 Add-ons 提供的。与各种 Add-ons 搭配在一起形成了各种各样的“套餐”。而最常见的组合应该就是如下这样的搭配:

react-test-renderer

在说 react-test-renderer 之前,让我们先聊聊什么是 renderer。React 最早是被用来开发网页的,所以早期的 React 库中还包含了大量和 DOM 相关的逻辑。后来 React 的设计思想慢慢被迁移到其它场景,最被人们熟知的莫过于 React Native 了。为了灵活性和扩展性,React 的代码被分拆为 React 核心代码与各种 renderer。React 自带了 3 个 renderer,前两个是大家常见的:

而今天提到的 react-test-renderer 则负责将组件输出成 JSON 对象以方便我们遍历、断言或是进行 snapshot 测试。

备注:这里有一份各种各样的 renderer 列表。

react-dom/test-utils

首先从名称可以看出这个库是包含在 react-dom 中的。所以它只是 react-dom 的辅助测试工具。在 React 文档站中它的介绍页上用的标题却只有 “Test Utilities” 两个单词,很容易让人产生误解。该库中的方法主要作用是帮我们遍历 ReactDOM 生成的 DOM 树,方便我们编写断言。注意:使用该库时必须提供一个 DOM 环境。当然这个 DOM 环境可以是 jsdom 这种模拟环境。(友情提示:Jest 默认的执行环境就是 jsdom)

读到这你可能会问,react-test-rendererreact-dom/test-utils 两者看起来还是很相似。何时该选择哪一个库呢?

了解的差不多了,该如何选择?

通过上文的描述,我们发现这些库可以分为两大类。

基于以下的考虑,我们最终选择了 Jest + react-test-rendererreact-dom/test-utils 的组合。