Jest

2024-06-27 17:49:09 454
Jest 是一个由 Facebook 开发和维护的 JavaScript 测试框架,专为确保代码的正确性和稳定性而设计。它支持断言库、Mock功能和自动化测试运行,适用于各种规模的 JavaScript 项目,尤其是在 React 应用程序中得到了广泛的应用。

特点

  1. 易于上手:Jest 的配置非常简单,开箱即用,只需很少的设置。
  2. 断言库内置:Jest 内置了断言库,无需额外引入其他库即可编写测试用例。
  3. 快照测试:支持快照测试,可以轻松捕获和比较 UI 组件的渲染输出。
  4. Mock 功能:内置 Mock 功能,可以轻松模拟模块和函数的行为。
  5. 代码覆盖率:自动生成详细的代码覆盖率报告,帮助开发者了解测试的覆盖范围。
  6. 并行测试:通过多线程并行运行测试,提高测试执行速度。
  7. 广泛的插件和社区支持:拥有丰富的插件生态系统和强大的社区支持。

使用场景

  1. 单元测试:用于验证个别函数或模块的功能是否正确。
  2. 集成测试:用于测试多个模块之间的交互和集成情况。
  3. 端到端测试:用于测试整个应用程序的功能和用户体验。
  4. 快照测试:用于测试 React 组件的渲染输出。

安装方式

使用 npm 或 Yarn 安装 Jest:

npm install --save-dev jest
# or
yarn add --dev jest

使用示例

基础测试

创建一个 sum.js 文件:

function sum(a, b) {
  return a + b;
}
module.exports = sum;

创建一个 sum.test.js 文件:

const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

package.json 中添加测试脚本:

{
  "scripts": {
    "test": "jest"
  }
}

运行测试:

npm test

快照测试

创建一个 React 组件 Link.js

import React from 'react';

function Link({ page, children }) {
  return <a href={page}>{children}</a>;
}

export default Link;

创建一个测试文件 Link.test.js

import React from 'react';
import renderer from 'react-test-renderer';
import Link from './Link';

test('renders correctly', () => {
  const tree = renderer.create(<Link page="https://www.example.com">Example</Link>).toJSON();
  expect(tree).toMatchSnapshot();
});

Mock 功能

创建一个文件 fetchData.js

function fetchData(callback) {
  setTimeout(() => {
    callback('peanut butter');
  }, 1000);
}

module.exports = fetchData;

创建一个测试文件 fetchData.test.js

const fetchData = require('./fetchData');

test('the data is peanut butter', done => {
  function callback(data) {
    expect(data).toBe('peanut butter');
    done();
  }

  fetchData(callback);
});

常用 API 介绍

  1. test(name, fn, timeout):定义一个测试用例。

    test('description', () => {
      // test code
    });
    
  2. expect(value):断言一个值,与各种匹配器结合使用。

    expect(sum(1, 2)).toBe(3);
    
  3. describe(name, fn):定义一个测试套件,将相关的测试用例分组。

    describe('Math functions', () => {
      test('adds 1 + 2 to equal 3', () => {
        expect(sum(1, 2)).toBe(3);
      });
    });
    
  4. beforeEach(fn, timeout):在每个测试用例运行之前执行的函数。

    beforeEach(() => {
      // setup code
    });
    
  5. afterEach(fn, timeout):在每个测试用例运行之后执行的函数。

    afterEach(() => {
      // teardown code
    });
    
  6. jest.fn():创建一个 mock 函数。

    const mockFn = jest.fn();
    
  7. jest.mock(moduleName, factory, options):自动 mock 模块。

    jest.mock('moduleName');
    

高级用法

并行测试

Jest 默认并行运行测试,利用多核 CPU 提高测试速度。可以通过设置 maxWorkers 参数来控制并行测试的数量。

jest --maxWorkers=4

自定义匹配器

Jest 允许创建自定义匹配器以增强测试断言功能:

expect.extend({
  toBeDivisibleBy(received, argument) {
    const pass = received % argument === 0;
    if (pass) {
      return {
        message: () => `expected ${received} not to be divisible by ${argument}`,
        pass: true,
      };
    } else {
      return {
        message: () => `expected ${received} to be divisible by ${argument}`,
        pass: false,
      };
    }
  },
});

test('10 is divisible by 2', () => {
  expect(10).toBeDivisibleBy(2);
});

官方资料