Jest:给你的 React 项目加上单元测试

这篇具有很好参考价值的文章主要介绍了Jest:给你的 React 项目加上单元测试。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

大家好,我是前端西瓜哥。

Jest 是一款轻量的 JavaScript 测试框架,它的卖点是简单好用,由 facebook 出品。本文就简单讲讲如何使用 Jest 对 React 组件进行测试。

为什么需要单元测试?

单元测试(Unit Testing),指的是对程序中的模块(最小单位)进行检查和验证。比如一个函数、一个类、一个组件,它们都是模块。

使用单元测试的优点:

  • 更好地交付高质量代码。代码不可能没有 bug,测试能帮你找出来;

  • 更容易重构。我们不愿意去重构代码,不去还技术债,很大原因是测试覆盖率不足,害怕遗漏一些边边角角的逻辑,导致线上发生重大事故;

  • 可以用测试描述模块功能。注释和文档容易忘记修改,但测试用例的描述永远是准确的,因为不对就无法通过测试;

  • 可测试性好的代码,往往可维护性更好。比如某个模块很难测试,是因为它和其他模块高度耦合,此时你需要替换为 依赖注入 的方式来管理模块依赖。

Jest 判定测试脚本

Jest 需要 确认哪些是测试文件,默认判断测试文件的逻辑是:

  • __tests__ 文件夹下的 .js .jsx.ts.tsx 为后缀的文件;

  • test.jsspec.js 或其他文件后缀 .jsx.ts.tsx

可以通过设置 Jest 配置文件的 testMatch 或 testRegex 选项进行修改,或者 package.json 下的 “jest” 属性。

Jest 基本使用

我们先写一个简单的函数,作为被测试的模块。

function sum(a, b) {
  return a + b;
}
export default sum;

然后我们用 Jest 来做测试。

import sum from './sum';

test('1 + 1 应该等于 2', () => {
  expect(sum(1, 1)).toBe(2);
});

然后执行 jest 命令,得到测试结果。

Jest:给你的 React 项目加上单元测试

test 方法创建了一个测试的作用域,该方法有三个参数:

  1. 测试的描述。

  2. 我们写测试代码的函数。

  3. 测试超时时间,默认为 5 秒,有些测试是异步的,我们需要等待。

test 方法有一个别名叫做 it,二者的功能是一致的,只是语义不同。通常用 test,但在某些情况下更适合用 it。这种情况就是 it 可以和描述语句拼成一句话的时候,比如:

it('should be true', () => { /* 测试内容 */});

it 方法和后面的 should be true 拼成了一句主语为 it 的句子,语义更好。

我们通常使用 expect 来测试一个模块的逻辑是否符合预期。expect 会将模块返回的结果封装成一个对象,然后提供非常丰富的方法做测试。

比如 toBe 就可以做 Object.is 的对比测试。

// sum(1, 1) 的结果是否为 2
expect(sum(1, 1)).toBe(2);

expect 的实现思路大致为:

function expect(value) {
  return {
    toBe(comparedValue) {
      if (Object.is(value, comparedValue)) {
        // 记录测试成功
      } else {
        // 记录测试失败
      }
    },
    // 其他 API
    toBeTruthy() { /* ... */ },
    // ...
  }
}

利用了闭包。

还有一些其他的 toXX API,我们称为 matcher。比如:

  • toEqual:对对象进行深递归的 Object.is 对比;

  • toBeTruthy:是否为真值;

  • not:对结果取反,比如 expect(val).not.beBe(otherVal) 表示两值不相等才通过测试;

  • toContain:数组中是否含有某个元素;

  • toBeLessThan:是否小于某个值,可以做性能测试,执行某个函数几千次,时间不能高于某个值。

更多 API 可以看文档:

https://jestjs.io/docs/expect

你可以用 describe 方法将多个相关的 test 组合起来,这样能让你的测试用例更好地被组织,测试报告输出也更有条理。

describe('一个有多个属性的对象的测试', () => {
  test('test 1', async () => {
    expect(obj.a).toBeTruthy();
  });

  test('test 2', async () => {
    expect(obj.b).toBeTruthy();
  });
});

describe 里面可以嵌套 describe,即组里面还可以有组。

异步测试

如果使用异步测试,需要将 Promise 作为返回值。

test('请求测试', () => {
  return getData().then(res => {
    expect(res.data.success).toBe(true);
  })
})

或使用 async / await。

test('请求测试', async () => {
  const res = await getData();
  expect(res.data.success).toBe(true);
})

也支持回调函数风格的测试,你需要调用函数传入的 done 函数来表明测试完成:

test('异步测试', done => {
  setTimeout(() => {
    expect('前端西瓜哥').toBeTruthy();
    done();
  }, 2000);
});

生命周期函数

beforeAll,在当前文件的正式开始测试前执行一次,适合做一些每次 test 前都要做的初始化操作,比如数据库的清空以及初始化。

beforeEach,在当前文件的每个 test 执行前都调用一次。

afterAll,在当前文件所有测试结束后执行一次,适合做一些收尾工作,比如将数据库清空。

afterEach,在当前文件的每个 test 执行完后都调用一次。

React Testing Library

本文不讲解安装和配置,我们先用 CreateReactApp 来搭建项目,并使用 TypeScript 模板。

yarn create react-app jest-app --template typescript

执行单元测试的命令为:

yarn test

CreateReactApp 内置了 Jest,但 Jest 本身并不支持 React 组件的测试 API,需要使用另外一个内置的 React Testing Library 库来测试 React 组件。

React Testing Library 是 以用户为角度 的测试库,能够模拟浏览器的 DOM,将 React 组件挂载上去后,我们使用其提供的一些模拟用户操作的 API 进行测试。

React Testing Library 的哲学是:

测试的写法越是接近应用被使用的方式,我们就越有自信将其交付给客户。

CreateReactApp 预置模板的 App.test.tsx 使用了 React Testing Library。

import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link', () => {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});

Enzyme

另一种比较流行的测试 React 组件的框架是 Enzyme,它的 API 简洁优雅,能够用类似 JQuery 的语法,对开发非常友好。Enzyme 由 Airbnd 出品,但目前已经不怎么维护了。

为此,你需要装一些包:

yarn add -D enzyme enzyme-adapter-react-16

如果你使用了 TS,你还得补上类型声明。

yarn add -D @types/enzyme @types/enzyme-adapter-react-16

示例:

import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Button from '../button';

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

it('Button with children', () => {
  const text = 'confirm';
  const btn = shallow(<Button>{text}</Button>);
  expect(btn.text()).toBe(text);
});

目前(2022.10.25) enzyme 官方只支持到 React 16,Enzyme 已死:

https://dev.to/wojtekmaj/enzyme-is-dead-now-what-ekl

使用 Jest 测试 React 组件

我们先实现一个简单的 Button 组件。

import { CSSProperties, MouseEvent, FC } from 'react';
import classNames from 'classnames';
import './style.scss';

const clsPrefix = 'xigua-ui-btn';

export type ButtonProps = {
  type?: 'primary' | 'default'
  size?: 'large' | 'middle' | 'small';
  disabled?: boolean;
  children?: React.ReactNode;
  onClick?: (event: MouseEvent) => void;
  style?: CSSProperties;
  className?: string;
}

const Button: FC<ButtonProps> = (props) => {
  const {
    type = 'default',
    size = 'middle',
    disabled = false,
    children,
    onClick,
    style,
    className,
  } = props;

  const mixedClassName = classNames(
    clsPrefix,
    `${clsPrefix}-${type}`,
    `${clsPrefix}-${size}`,
    className
  );

  return (
    <button
      style={style}
      className={mixedClassName}
      disabled={disabled}
      onClick={onClick}
    >
      {children}
    </button>
  );
};

export default Button;

然后我们创建一个 button.test.tsx 测试文件。我们使用 React Testing Library。

我们写个测试。

import { render, screen } from '@testing-library/react';
import Button from '../button';

test('Button with children', () => {
  const text = 'confirm Btn';
  render(<Button>{text}</Button>);

  screen.debug();
});

render 方法会将 React 组件挂载到虚拟的文档树上。screen.debug() 用于调试,能让我们看到虚拟树的完整结构。

<body>
  <div>
    <button
      class="xigua-ui-btn xigua-ui-btn-default xigua-ui-btn-middle"
    >
      confirm Btn
    </button>
  </div>
</body>

测试 Button 的文本内容是否正常显示:

test('Button with children', () => {
  const text = 'confirm Btn';
  // 渲染 Button 组件
  render(<Button>{text}</Button>);
  
  // 找到内容为 text 的元素
  const BtnElement = screen.getByText(text);
  // 测试元素是否在 Document 上
  expect(BtnElement).toBeInTheDocument();
});

测试 Button 的 onClick 能否正常触发:

test('Button click', () => {
  let toggle = false;
  render(<Button onClick={() => { toggle = true; }} />);

  // 找到第一个 button 元素,然后触发它的点击事件 
  fireEvent.click(screen.getByRole('button'));
  // 看看 toggle 变量是否变成 true
  expect(toggle).toBe(true);
});

测试 Button 的 className 是否成功添加:

test('Button with custom className', () => {
  const customCls = 'customBtn';
  render(<button className={customCls} />);

  // 找到按钮元素
  const btn = screen.getByRole('button');
  // 元素的 className 列表上是否有我们传入的 className
  expect(btn).toHaveClass(customCls);
});

源码:

https://github.com/F-star/xigua-ui/blob/main/src/components/button/tests/button.test.tsx

执行 yarn test

Jest:给你的 React 项目加上单元测试

结尾

为了让代码更健壮,做模块的单元测试还是有必要的,Jest 作为流行的测试库值得一试。

我是前端西瓜哥,欢迎关注我,学习更多前端知识。文章来源地址https://www.toymoban.com/news/detail-493833.html

到了这里,关于Jest:给你的 React 项目加上单元测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 只用3步,给你的日语视频加上中日双语字幕

    很多日语电影或者日剧,都没有带字幕。对于想马上看到视频,但是又不懂日语的朋友来说,就只能等字幕组做好字幕发出来才能看了。 这里教大家用33字幕这个软件,去给影片快速生成中日双语字幕,让你在第一时间就能欣赏影片内容。 废话不多说,下面让我们开始吧。

    2024年02月04日
    浏览(17)
  • 快速上手 Jest 单元测试框架:使用 Jest Preset 加速配置,灵活应对项目需求

    Jest preset 参数的作用是提供一个预先定义好的配置集合,以便于快速开始使用 Jest 单元测试框架。你可以选择现有的 preset,如 jest-preset-angular 、 create-react-app 或自定义 preset,以根据你的项目需求自动应用一系列配置。 使用示例: 先安装一个现有的 preset,例如 jest-preset-angul

    2024年02月06日
    浏览(18)
  • vue-cli 项目集成 Jest 单元测试

    前端单元测试对于保证代码质量和稳定性是非常重要的。 为什么需要单元测试: 检测bug; 提升回归效率; 保证代码质量。  ①、Mocha 比较灵活成熟,但没有内部集成,需要自主选择断言库和监听库。。 ②、Jasmine 是 Jest 的底层库,助攻 BDD(即行为驱动开发)断言库与异步测

    2024年01月17日
    浏览(24)
  • 什么是 Jest ? Vue2 如何使用 Jest 进行单元测试?Vue2 使用 Jest 开发单元测试实例

    Jest 是一个流行的 JavaScript 测试框架,由 Facebook 开发并维护,专注于简单性和速度。它通常用于编写 JavaScript 和 TypeScript 应用程序的单元测试、集成测试和端到端测试。 特点: 简单易用: Jest 提供简洁的 API 和易于理解的语法,使得编写测试用例变得简单快捷。 零配置:

    2024年01月25日
    浏览(20)
  • Jest单元测试(一)

    Jest是Facebook一套开源的 JavaScript 测试框架,它自动集成了断言、JSDom、覆盖率报告等测试工具。 他适用但不局限于使用以下技术的项目:Babel, TypeScript, Node, React, Angular, Vue 官网地址:https://jestjs.io/en/ 使用 yarn 安装 Jest︰ 或 npm: 注:Jest的文档统一使用yarn命令,不过使用npm也

    2024年02月16日
    浏览(18)
  • vue jest单元测试

    vue-test-utils 提供了两种方式用于渲染,或者说 加载(mount) 一个组件 — mount 和 shallowMount 。一个组件无论使用这两种方法的哪个都会返回一个 wrapper ,也就是一个包含了 Vue 组件 的对象,辅以一些对测试有用的方法。 mount : 会渲染子组件 shallowMount :会加载子组件,不会被

    2024年02月05日
    浏览(14)
  • 如何使用Jest进行单元测试

    Jest 是一种流行的 JavaScript 测试框架,它具有易用性和高效性。Jest 支持测试各种 JavaScript 应用程序,包括 React、Vue、Node.js 等。在本文中,我们将介绍如何使用 Jest 进行单元测试。 ## 1. 安装 Jest 首先,我们需要在项目中安装 Jest。可以使用 npm 或 yarn 安装 Jest: ``` npm install

    2024年02月10日
    浏览(17)
  • vue 引入jest 单元测试

    为什么要搞单元测试,好处有什么。 提测需要, 代码覆盖率达到95%,分支覆盖率达到100% ,不达到要求,不给测。 确保代码正确性。单元测试可以检测和发现代码中的错误,在开发期间及时纠正。 提高代码质量。进行单元测试可以思考更多场景,添加边界测试用例,找到更

    2024年01月18日
    浏览(18)
  • 单元测试(jest):理解、安装、使用

    一、理解单元测试的重要性 bug发现在开发阶段,成本很低, 如果发现在生产环境,成本很高, 如果是关键时刻,决定人生命运,决定企业发展。 从技术的角度讲,有效的提高代码的健壮性,有效的增加代码的可维护性,对于后期的代码重构是必要条件。 从团队的角度讲,

    2024年02月03日
    浏览(18)
  • vue+jest 单元测试配置+用例

    目录 目录 1 Jest 说明文档 2 1、 搭建node环境包 2 这里安装环境是node 18,npm 9.5.0。 2 Test Runner 2 2、 安装jest 3 Jest安装步骤 4 项目的根目录下创建一个.babelrc 配置文件: 4 在项目的根目录下创建 jest.config.js 4 3、 全局设定 5 预处理和后处理 5 方法 6 4、 断言 6 真假断言 6 数字断言

    2024年02月07日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包