如何使用 Jest 为 React 组件编写快照测试

介绍

Snapshot 测试允许您确保您的输出继续按预期行为,这是有用的,因为当您重新浏览代码以进行更新时,这些更改可能会导致某些事情发生故障的可能性增加。

与严格的测试驱动开发(TDD)不同,其中标准做法是先写失败的测试,然后写代码来通过测试,即时测试采取了不同的方法。

在为 React 组件编写快照测试时,您首先需要在工作状态下进行代码。然后,根据某些数据生成预期输出快照。快照测试与组件一起进行。

在测试失败的情况下,这可能意味着两件事。如果测试结果是意想不到的,您可能需要解决您的组件的问题。如果测试结果是预期的,这可能意味着即时测试需要更新以支持新输出。

在本教程中,您将探索即时测试以及如何使用它们来确保您的用户界面(UI)不会意外改变。

前提条件

要完成本教程,您将需要:

本教程还使用 Visual Studio Code作为代码编辑器,以便运行集成终端。

本教程已通过 Node v14.7.0、npm v6.14.7、react v16.13.1 和jest v24.9.0 进行验证。

步骤 1 – 创建一个 React 组件来测试

首先,要想测试一些东西,你需要使用 Create React App创建一个 React 应用程序。

打开终端并执行以下命令:

1npx [email protected] react-snapshot-tests

然后,更改到新创建的应用程序目录:

1cd react-snapshot-tests

接下来,开始应用程序:

1npm start

在此时刻,你现在应该有一个 React 应用程序运行,并可以在网页浏览器中查看它,然后你需要创建一个可以测试的组件。

对于本教程的目的,你要创建的组件会返回它所接收的项目附加值。

在您的终端中,在src下创建一个组件子目录:

1mkdir src/components

然后,创建一个Items.js组件:

1nano src/components/Items.js

将以下代码添加到Items.js:

 1[label src/components/Items.js]
 2import React from 'react';
 3import PropTypes from 'prop-types';
 4
 5/**
 6 * Render a list of items
 7 *
 8 * @param {Object} props - List of items
 9 */
10function Items(props) {
11  const { items = [] } = props;
12
13  // A single item in the list, render a span.
14  if (items.length === 1) {
15    return <span>{items[0]}</span>;
16  }
17
18  // Multiple items on the list, render a list.
19  if (items.length > 1) {
20    return (
21      <ul>
22        {items.map(item => <li key={item}>{item}</li>)}
23      </ul>
24    );
25  }
26
27  // No items on the list, render an empty message.
28  return <span>No items in list</span>;
29}
30
31Items.propTypes = {
32  items: PropTypes.array,
33};
34
35Items.defaultProps = {
36  items: []
37};
38
39export default Items;

此代码将根据金额显示项目奖励:

  • 如果有多个项目,则项目将显示在未分类的列表中(<ul>)。 *如果有一个项目,则该项目将显示在一个 <span> 元素中 *如果没有项目,则会显示错误消息

最后,更新App.js以使我们的组件:

1nano src/App.js

App.js的内容替换为以下内容:

 1[label src/App.js]
 2import React, { Component } from 'react';
 3import Items from './components/Items';
 4
 5class App extends Component {
 6  render() {
 7    const items = [
 8      'Shark',
 9      'Dolphin',
10      'Octopus'
11    ];
12    return (
13      <Items items={items} />
14    );
15  }
16}
17
18export default App;

如果您在浏览器中访问应用程序,则会出现一个显示在App.js中设置的值列表的屏幕:

1[secondary_label Output]
2* Shark
3* Dolphin
4* Octopus

由于有多个项目,它将显示为未分类的列表。

接下来,您将添加您的快照测试。

步骤2 - 写 Snapshot 测试

要开始,请删除由 Create React App 生成的 App.test.js 文件:

1rm src/App.test.js

这个教程不需要它。

接下来,安装 react-test-renderer,一个库,允许您将 React 组件渲染为 JavaScript 对象,而无需 DOM。

1npm install [email protected]

要开始,您将创建一个Items.test.js文件:

1nano src/components/Items.test.js

编写一个测试,该测试将项目组件转换为没有通过作为奖励的项目:

 1[label src/components/Items.test.js]
 2import React from 'react';
 3import renderer from 'react-test-renderer';
 4
 5import Items from './Items';
 6
 7it('renders correctly when there are no items', () => {
 8  const tree = renderer.create(<Items />).toJSON();
 9  expect(tree).toMatchSnapshot();
10});

接下来,让我们运行测试 Create React App 处理了设置测试的所有初始化:

1npm test

你应该得到一个通过测试当没有项目时正确返回:

A passing test!

当您首次运行快照测试时,请注意在__snapshots__目录中创建一个新的快照文件,因为你的测试文件被命名为Items.test.js,所以快照文件被适当命名为Items.test.js.snap

Items.tests.js.snap的内容应该看起来像:

1[label src/components/__snapshots__/Items.test.js.snap]
2// Jest Snapshot v1, https://goo.gl/fbAQLP
3
4exports[`renders correctly when there are no items 1`] = `
5<span>
6  No items in list
7</span>
8`;

此快照与组件的精确输出相匹配。

它使用 pretty-format来使快照文件可以人读。

现在,您可以创建两个其他场景的测试,其中有一个项目和多个项目。

打开Items.tests.js:

1nano src/components/Items.test.js

添加以下代码行:

 1[label src/components/Items.test.js]
 2// ...
 3
 4it('renders correctly when there is a single item', () => {
 5  const items = ['one'];
 6  const tree = renderer.create(<Items items={items} />).toJSON();
 7  expect(tree).toMatchSnapshot();
 8});
 9
10it('renders correctly when there are multiple items', () => {
11  const items = ['one', 'two', 'three'];
12  const tree = renderer.create(<Items items={items} />).toJSON();
13  expect(tree).toMatchSnapshot();
14});

在这个时候,你有三个测试写的:一个没有项目,一个单个项目,另一个多个项目。

重启测试:

1npm test

所有三个测试都应该顺利通过,你现在将在你的__snapshots__目录中有三个快照。

接下来,您将通过更新快照测试来解决失败的测试。

步骤 3 – 更新 Snapshot 测试

为了更好地了解为什么您需要即时测试,您将引入项目组件的更改,并重新运行测试,这将代表对正在开发中的项目进行更改时会发生什么的模拟。

打开Items.js:

1nano src/components/Items.js

将类名称添加到spanli元素中:

 1[label src/components/Items.js]
 2...
 3/**
 4 * Render a list of items
 5 *
 6 * @param {Object} props - List of items
 7 */
 8function Items(props) {
 9  const { items = [] } = props;
10
11  // A single item in the list, render a span.
12  if (items.length === 1) {
13    return <span className="item-message">{items[0]}</span>;
14  }
15
16  // Multiple items on the list, render a list.
17  if (items.length > 1) {
18    return (
19      <ul>
20        {items.map(item => <li key={item} className="item-message">{item}</li>)}
21      </ul>
22    );
23  }
24
25  // No items on the list, render an empty message.
26  return <span className="empty-message">No items in list</span>;
27}
28
29Items.propTypes = {
30  items: PropTypes.array,
31};
32
33Items.defaultProps = {
34  items: [],
35};
36
37export default Items;

让我们重启测试:

1npm test

您将看到失败的测试结果:

Failing tests

Jest 匹配了现有的截图与渲染的组件的更改,并未成功,因为您的组件有一些添加,然后显示了向截图测试引入的更改的差异。

如果更改未预期,则在部署更改之前您已经发现了错误,现在可以解决错误,如果更改预期,则需要更新您的快照测试以使其正确通过。

对于教程,您可以假设这是一个预期的变化. 您打算将类名称添加到组件中。

虽然 Jest 处于交互式模式,但您可以通过按u按下提供的选项来更新快照测试:

Watch Mode Options

<$>[注] 注: 另外,如果您有 Jest 全球安装,您可以运行 jest --updateSnapshotjest -u. <$>

这将更新快照,以匹配您所做的更新,您的测试将通过。

以下是以前的没有项目的快照测试:

 1[label src/components/__snapshots__/Items.test.js.snap]
 2//  ...
 3
 4exports[`renders correctly when there are no items 1`] = `
 5<span>
 6  No items in list
 7</span>
 8`;
 9
10//  ...

以下是对没有项目的新更新的快照测试:

 1[label src/components/__snapshots__/Items.test.js.snap]
 2//  ...
 3
 4exports[`renders correctly when there are no items 1`] = `
 5<span
 6  className="empty-message"
 7>
 8  No items in list
 9</span>
10`;
11
12// ...

更新测试后,他们将通过:

Passing tests

如果这是一个正在开发的项目,你可以部署代码,知道你打算的更改被记录在未来的开发。

结论

在本教程中,您为 React 组件撰写了即时测试,您还修改了组件以体验失败测试,最后您更新了即时测试以修复测试。

这个测试循环通过,失败,并解决失败将是您的开发工作流的一部分。

Snapshot测试是许多不同的测试工具之一,因此,您可能仍然需要为您的行动和减速器写测试。

虽然你已经探索了快照测试的基本知识,但你可以学到很多关于写更好的快照测试。 请从Jest的文档中查看 快照最佳实践以了解更多关于快照测试的信息。

如果您想了解更多关于 React 的信息,请参阅 我们的 React 主题页面以获取练习和编程项目。

Published At
Categories with 技术
comments powered by Disqus