使用Jest在React中测试组件:基础

使用Jest在React中测试组件:基础_第1张图片 您将要创造的

对许多开发人员而言,测试代码是一种令人困惑的做法。 这是可以理解的,因为编写测试需要更多的精力,更多的时间和预见可能的用例的能力。 由于缺少资源和人力,初创公司和从事较小项目的开发人员通常倾向于完全忽略测试。

但是,我认为应该测试组件的原因有两个:

  1. 它使您对代码更有信心。
  2. 测试可以提高您的生产力。

React也没有什么不同。 当您的整个应用程序开始变成一堆难以维护的组件时,测试将提供稳定性和一致性。 从第一天开始编写测试将帮助您编写更好的代码,轻松发现错误并维护更好的开发工作流程。

在本文中,我将带您了解为React组件编写测试所需的一切。 我们还将介绍一些最佳实践和技巧。 让我们开始吧!

在React中测试组件

测试是验证我们的测试断言是正确的,并在应用程序的整个生命周期中保持不变的过程。 测试断言是一个布尔表达式,除非代码中存在错误,否则该布尔表达式将返回true。

例如,一个断言可以像这样简单:“当用户导航到/ login时 ,应该呈现一个ID为#login的模式。” 因此,如果事实证明您以某种方式弄乱了登录组件,则断言将返回false。 断言不仅限于呈现的内容,您还可以断言应用程序如何响应用户交互和其他操作。

前端开发人员使用许多自动测试策略来测试其代码。 我们将讨论仅限于React中流行的三种软件测试范例:单元测试,功能测试和集成测试。

单元测试

单元测试是在测试界中仍然很流行的测试资深人士之一。 顾名思义,您将测试各个代码段,以验证它们是否按预期独立运行。 由于React的组件架构,单元测试是很自然的选择。 它们也更快,因为您不必依赖浏览器。

单元测试可帮助您隔离地考虑每个组件,并将其视为功能。 您对特定组件的单元测试应回答以下问题:

  1. 有道具吗? 如果是,这对他们有什么影响?
  2. 它呈现什么成分?
  3. 应该有状态吗? 它何时或如何更新状态?
  4. 安装或卸载时,或者在用户交互时,应遵循什么程序?

功能测试

功能测试用于测试应用程序一部分的行为。 功能测试通常是从用户的角度编写的。 功能通常不限于单个组件。 它可以是完整的表单,也可以是整个页面。

例如,在构建注册表单时,它可能涉及表单元素,警报和错误(如果有)的组件。 提交表单后呈现的组件也是该功能的一部分。 这不需要浏览器渲染器,因为我们将在测试中使用内存中的虚拟DOM。

整合测试

集成测试是一种测试策略,其中所有单个组件都作为一组进行测试。 集成测试试图通过在实际的浏览器上运行测试来复制用户体验。 这比功能测试和单元测试要慢得多,因为每个测试套件都是在实时浏览器上执行的。

在React中,单元测试和功能测试比集成测试更受欢迎,因为它们易于编写和维护。 这就是我们将在本教程中介绍的内容。

了解您的工具

您需要某些工具和依赖项才能开始对React应用程序进行单元和功能测试。 我在下面列出了它们。

笑话测试框架

Jest是一个需要零配置的测试框架,因此易于设置。 它比Jasmine和Mocha之类的测试框架更受欢迎,因为它是由Facebook开发的。 笑话也比其他人快,因为它使用了一种聪明的技术来并行化跨工作人员的测试运行。 除此之外,每个测试都在沙盒环境中运行,以避免两个连续测试之间的冲突。

如果您使用的是create-react-app,则Jest附带了该应用程序。 如果没有,您可能必须安装Jest和其他一些依赖项。 您可以在Jest官方文档页面上阅读有关它的更多信息。

反应测试渲染器

即使您使用的是create-react-app,也需要安装此软件包才能呈现快照。 快照测试是Jest库的一部分。 因此,您可以使用测试渲染器快速呈现虚拟DOM的可序列化HTML输出,而不是呈现整个应用程序的UI。 您可以按以下方式安装它:

yarn add react-test-renderer

ReactTestUtils和酶

react-dom / test-utils由React团队提供的一些测试实用程序组成。 或者,您可以使用由Airbnb发布的Enzyme软件包。 酶比ReactTestUtils好得多,因为它很容易断言,操纵和遍历React组件的输出。 我们将从React utils开始测试,然后再过渡到Enzyme。

要安装酶,请运行以下命令。

yarn add enzyme enzyme-adapter-react-16

将代码添加到src / SetupTests.js

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

在create-react-app页面的“ 测试组件”部分中有关于此的更多信息。

设置演示应用程序并组织测试

我们将为一个简单的演示应用程序编写测试,该演示程序显示产品列表的主视图/详细视图。 您可以在我们的GitHub存储库中找到演示应用程序。 该应用程序包含一个称为ProductContainer的容器组件和三个演示组件: ProductList ProductDetailsProductHeader

目录结构

.
├── package-lock.json
├── package.json
├── public
│   ├── index.html
│   └── manifest.json
├── src
│   ├── components
│   │   ├── App.js
│   │   ├── ProductContainer.js
│   │   ├── ProductDetails.jsx
│   │   ├── ProductHeader.js
│   │   ├── ProductList.jsx
│   ├── index.js
│   └── style.css

该演示非常适合单元测试和功能测试。 您可以单独测试每个组件和/或测试整个产品列表功能。

下载演示文件后,创建名称为__tests__的目录。  / src / components /中 。 然后,您可以将与此功能相关的所有测试文件存储在__tests__目录中。 测试人员通常命名他们的测试文件,无论是.spec.js.test.js -例如,ProductHeader.test.jsProductHeader.spec.js。

在React中编写基本测试

如果尚未创建一个ProductHeader.test.js文件。 我们的测试基本上是这样的:

src / components / __ tests __ / ProductList.test.js

describe('ProductHeader', () => {

  it('passing test', () => {
    expect(true).toBeTruthy();
  })

  it('failing test', () => {
    expect(false).toBeTruthy();
  })
})

测试套件以describe块开头,这是一个接受两个参数的全局Jest函数。 第一个参数是测试套件的标题,第二个参数是实际的实现。 测试套件中的每个it()都对应一个测试或规范。 一个测试包含一个或多个检查代码状态的期望。

expects(true).toBeTruthy();

在Jest中,期望是返回true或false的断言。 当规范中的所有断言都为真时,就说是通过了。 否则,测试将失败。

例如,我们创建了两个测试规范。 第一个显然应该通过,而第二个应该失败。

注意: toBeTruthy()是预定义的匹配器。 在Jest中,每个匹配器都会在期望值和实际值之间进行比较,并返回一个布尔值。 还有更多可用的匹配器,我们稍后将对其进行介绍。

运行测试套件

create-react-app已设置执行测试套件所需的所有内容。 您所需要做的就是运行以下命令:

yarn test

您应该会看到以下内容:

使用Jest在React中测试组件:基础_第2张图片

要使测试通过失败,必须将toBeTruthy()匹配器替换为toBeFalsy()

expects(false).toBeFalsy();

而已!

在Jest中使用Matchers

如前所述,Jest使用匹配器比较值。 您可以使用它来检查相等性,比较两个数字或字符串以及验证表达式的真实性。 这是Jest中可用的流行匹配器列表。

  • toBe();
  • toBeNull()
  • toBeDefined()
  • toBeUndefined()
  • toBeTruthy()
  • toBeFalsy()
  • toBeGreaterThan()
  • toBeLesserThan()
  • toMatch()
  • toContain()

这只是一种味道。 您可以在参考文档中找到所有可用的匹配器。

测试React组件

首先,我们将为ProductHeader组件编写一些测试。 如果尚未打开ProductHeader.js文件

src / components / ProductHeader.js

import React, {Component} from 'react';
   
class ProductHeader extends Component  {
    render() {
        return(
            

Product Listing Page

); } }; export default ProductHeader;

您是否想知道为什么我在这里使用类组件而不是功能组件? 原因是使用ReactTestUtils测试功能组件更加困难。 如果您想知道为什么,那么此Stack Overflow讨论会提供答案。

我们可以根据以下假设编写测试:

  1. 该组件应呈现一个h2标签。
  2. h2标签应具有一个名为title的类。

要渲染组件并检索相关的DOM节点,我们需要ReactTestUtils。 删除虚拟规格并添加以下代码:

src / components / __ tests __ / ProductHeader.test.js

import React from 'react';
import ReactTestUtils from 'react-dom/test-utils'; 
import ProductsList from '../ProductsList';

describe('ProductHeader Component', () => {

    it('has an h2 tag', () => {
     //Test here
    });
  
    it('is wrapped inside a title class', () => {
     //Test here
    })
  })

为了检查是否存在h2节点,我们首先需要将React元素渲染到文档中的DOM节点中。 您可以借助ReactTestUtils导出的一些API来做到这ReactTestUtils 。 例如,要呈现我们的组件,您可以执行以下操作:

const component = ReactTestUtils.renderIntoDocument();

然后,您可以在findRenderedDOMComponentWithTag('tag-name')的帮助下从组件中提取h2标签。 它检查所有子节点,并找到与tag-name匹配的节点。

这是整个测试规格。

it('has an h2 tag', () => {

      const component = ReactTestUtils.renderIntoDocument();    
      var h2 = ReactTestUtils.findRenderedDOMComponentWithTag(
       component, 'h2'
     );
    
  });

尝试保存它,测试运行器应向您显示测试已通过。 这有点令人惊讶,因为我们没有前面的示例中的expect()语句。 ReactTestUtils导出的大多数方法都内置了期望。 在这种特殊情况下,如果测试实用程序未能找到h2标签,它将抛出错误,并且测试将自动失败。

现在,尝试为第二个测试创建代码。 您可以使用findRenderedDOMcomponentWithClass()来检查是否存在带有“ title”类的节点。

it('has a title class', () => {

      const component = ReactTestUtils.renderIntoDocument();    
      var node = ReactTestUtils.findRenderedDOMComponentWithClass(
       component, 'title'
     );
    })

而已! 如果一切顺利,您应该看到绿色的结果。

使用Jest在React中测试组件:基础_第3张图片

结论

尽管我们只是编写了两个测试规范,但在此过程中我们涵盖了很多基础。 在下一篇文章中,我们将为产品列表页面编写一些成熟的测试。 我们还将用Enzyme替换ReactTestUtils。 为什么? 酶提供了易于使用且对开发人员友好的高级界面。 请继续关注第二部分!

如果您在任何时候感到困惑或需要帮助,请在评论中告知我们。

翻译自: https://code.tutsplus.com/articles/testing-components-in-react-using-jest-the-basics--cms-28934

你可能感兴趣的:(单元测试,java,python,vue,javascript)