5分钟掌握Jest单元测试:从零到实战的JavaScript测试指南

1. 项目概述:为什么我们需要Jest?

如果你写过JavaScript代码,尤其是稍微复杂一点的业务逻辑,那么下面这个场景你一定不陌生:你修改了一个函数,然后心惊胆战地刷新页面,祈祷它不会影响到其他看似无关的功能。或者,你重构了一段代码,结果上线后半夜被报警电话叫醒,因为某个你完全没想到的边角情况崩了。这种“牵一发而动全身”的恐惧,是每个开发者都经历过的噩梦。

测试,就是对抗这种噩梦最有效的武器。而Jest,则是当前JavaScript生态中,这把武器最趁手、最锋利的一个。它由Facebook开源并维护,最初是为了测试React应用而生,但凭借其“零配置”的理念、强大的功能和极佳的开发体验,迅速成为了整个JavaScript社区单元测试的事实标准。无论是Node.js后端服务、React/Vue前端组件,还是普通的工具库,Jest都能轻松应对。

你可能觉得写测试很麻烦,是浪费时间。但我想告诉你一个反直觉的事实: 写好测试,是提升开发效率最快的方式之一 。它带来的好处远不止“保证代码正确”这么简单:

  1. 即时反馈,提升信心 :你不再需要手动点击页面、输入数据来验证逻辑。写完代码,运行测试,几秒钟内就能知道它是否按预期工作。这种即时反馈能极大提升你的开发信心和节奏。
  2. 充当活文档 :一个好的测试用例,本身就是对函数功能和使用方法最清晰的说明。新同事接手代码,看测试比看晦涩的业务逻辑要直观得多。
  3. 支持安全重构 :这是测试最大的价值。当你需要优化代码结构、修复技术债务时,完备的测试套件就是你的安全网。只要所有测试都通过,你就可以确信你的改动没有破坏原有功能。
  4. 促进更好的设计 :为了让代码易于测试,你自然会倾向于编写职责单一、接口清晰、耦合度低的模块。这本身就是优秀软件设计的核心原则。

而Jest,将写测试的门槛降到了最低。它内置了测试运行器、断言库、Mock工具和覆盖率报告,你几乎不需要任何额外配置就能开始。它模拟了浏览器的DOM环境(通过 jsdom ),让你能在Node.js环境下测试前端代码。它的watch模式可以监听文件变化自动运行测试,体验丝滑。今天,我们就用5分钟,彻底掌握用Jest编写第一个测试用例的核心要领,让你从此告别“盲改代码”的时代。

2. 环境准备与项目初始化

在开始写测试之前,我们需要先把Jest这个工具安装到项目中,并进行最基础的配置。别担心,这个过程简单到超乎想象。

2.1 创建项目与安装Jest

首先,你需要一个Node.js项目。如果你还没有,可以随便创建一个文件夹,然后初始化它。

# 创建一个新的项目目录
mkdir my-first-jest-test
cd my-first-jest-test

# 初始化npm项目(一路回车即可)
npm init -y

现在,我们来安装Jest。Jest既可以全局安装,但更推荐作为项目的开发依赖(devDependencies)安装,这样可以保证团队每个成员和CI/CD环境都使用完全相同的版本。

# 使用npm安装
npm install --save-dev jest

# 或者使用yarn
yarn add --dev jest

安装完成后,你的 package.json 文件中会自动添加Jest的依赖。同时,我们修改一下 package.json ,添加一个运行测试的脚本命令,这会让我们后续的操作更方便。

{
  "name": "my-first-jest-test",
  "version": "1.0.0",
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "jest": "^29.7.0"
  }
}

注意 :这里 scripts 里的 test 命令,直接写 jest 即可。当你运行 npm test yarn test 时,npm/yarn会自动去 node_modules/.bin 目录下找到Jest的可执行文件来运行。这是一种标准做法。

2.2 理解Jest的默认约定

Jest之所以号称“零配置”,是因为它有一套非常合理的默认约定。了解这些约定,你就能知道把测试文件放在哪里、如何命名。

  • 测试文件识别 :Jest默认会查找项目中所有以 .test.js .spec.js 结尾的文件,或者放在 __tests__ 目录下的 .js 文件。例如, sum.test.js __tests__/sum.js 都会被识别为测试文件。
  • 测试运行 :当你执行 npm test 时,Jest会自动运行所有它找到的测试文件。
  • 模块系统 :Jest默认支持ES Module( import/export )和CommonJS( require/module.exports )语法,你不需要额外配置Babel(对于较新的Node.js版本或通过配置支持)。

对于一个小型或新项目,你完全不需要创建任何配置文件,直接按照约定写测试文件就行。Jest的智能默认值已经能处理大多数情况。

2.3 编写第一个被测试的函数

测试总得有个对象。我们先创建一个非常简单的函数作为测试目标。在项目根目录下创建一个 math.js 文件:

// math.js
function sum(a, b) {
  return a + b;
}

module.exports = { sum };

这个 sum 函数简单到令人发指,但它是一个完美的起点。我们接下来就要为它编写测试,验证它是否真的能正确完成加法。

3. 编写你的第一个测试用例

万事俱备,现在让我们动手编写第一个测试文件。按照Jest的约定,我们创建一个名为 math.test.js 的文件,和 math.js 放在同一目录下。

3.1 测试文件的结构与语法

打开 math.test.js ,输入以下内容:

// math.test.js
const { sum } = require('./math');

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

让我们逐行拆解这个最简单的测试用例:

  1. 导入被测模块 const { sum } = require(‘./math’);

    • 这行代码引入了我们想要测试的 sum 函数。如果你使用ES Module,可以写成 import { sum } from ‘./math.js’;
  2. test 函数 test(‘adds 1 + 2 to equal 3’, () => { … });

    • 这是Jest定义单个测试用例的核心函数。它接受两个参数:
      • 第一个参数(字符串) :测试用例的描述。这个描述应该清晰、具体地说明这个测试在验证什么。好的描述能在测试失败时让你快速定位问题,例如“当输入为空字符串时返回默认值”。
      • 第二个参数(函数) :包含实际测试逻辑的函数。Jest会执行这个函数。
  3. expect toBe (断言) expect(sum(1, 2)).toBe(3);

    • 这是测试的灵魂——断言。它的逻辑是:“我 期望 sum(1,2) 结果 toBe (等于) 3 ”。
    • expect() :接收一个值,这个值通常是你调用被测函数得到的结果(称为“实际值”)。
    • .toBe() :这是一个“匹配器”(Matcher)。它用来比较 expect 传入的实际值是否符合某个条件(这里条件是等于 3 )。Jest提供了几十个不同的匹配器来处理各种情况(是否相等、是否为真、是否包含某元素、是否抛出错误等)。

3.2 运行测试并查看结果

现在,在终端中运行我们之前配置好的测试命令:

npm test
# 或
yarn test

你会看到类似下面的输出:

 PASS  ./math.test.js
  ✓ adds 1 + 2 to equal 3 (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.234 s
Ran all test suites.

恭喜!你的第一个测试用例通过了。Jest给出了清晰的反馈:一个绿色的对勾(✓),告诉我们测试用例“adds 1 + 2 to equal 3”通过了。下面还总结了测试套件和测试用例的通过情况。

3.3 让测试失败:理解错误报告

一个只能通过的测试不是好测试。我们故意写一个错误的断言,看看Jest如何报告失败。

修改 math.test.js ,将 toBe(3) 改为 toBe(4)

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(4); // 这显然是错的
});

再次运行 npm test ,你会看到红色的错误报告:

 FAIL  ./math.test.js
  ✕ adds 1 + 2 to equal 3 (3 ms)

  ● adds 1 + 2 to equal 3

    expect(received).toBe(expected) // Object.is equality

    Expected: 4
    Received: 3

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

      at Object.<anonymous> (math.test.js:4:21)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.247 s
Ran all test suites.

这个报告非常详细:

  • 表示测试失败。
  • 后面是失败的测试描述。
  • 最关键的部分 :它清晰地指出了断言失败的原因。 Expected: 4 表示你期望的值, Received: 3 表示实际得到的值。一眼就能看出是哪里不对。
  • 它还指出了错误发生的具体位置( math.test.js 第4行第21列),方便你快速定位。

请把断言改回正确的 toBe(3) ,我们继续。

实操心得 测试失败的报告和测试通过的结果同样重要,甚至更重要。 养成习惯,在编写测试时, 先故意让它失败一次 ,确保你写的断言确实在检查你想要检查的东西,并且错误信息是你能够理解的。这能有效避免“假通过”的测试(比如断言永远为真)。

4. Jest核心概念深度解析

掌握了第一个测试用例后,我们来深入了解一下Jest的几个核心概念,它们是你编写有效测试的基石。

4.1 测试套件( describe )组织多个测试

当你有多个相关的测试用例时,可以用 describe 函数将它们分组,形成一个测试套件。这能让你的测试结构更清晰,报告也更易读。

让我们为 math.js 添加一个 subtract 函数,并一起测试。

// math.js 更新
function sum(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

module.exports = { sum, subtract };

然后更新测试文件:

// math.test.js 更新
const { sum, subtract } = require('./math');

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

  test('adds 5 + 7 to equal 12', () => {
    expect(sum(5, 7)).toBe(12);
  });

  test('subtracts 5 - 3 to equal 2', () => {
    expect(subtract(5, 3)).toBe(2);
  });

  test('subtracts 0 - 1 to equal -1', () => {
    expect(subtract(0, 1)).toBe(-1);
  });
});

运行测试,输出会是这样:

 PASS  ./math.test.js
  math functions
    ✓ adds 1 + 2 to equal 3 (1 ms)
    ✓ adds 5 + 7 to equal 12
    ✓ subtracts 5 - 3 to equal 2
    ✓ subtracts 0 - 1 to equal -1

看,所有测试都被归在了“math functions”这个套件下,层次分明。 describe 可以嵌套使用,用于构建更复杂的测试结构,例如按模块或按功能分组。

4.2 常用匹配器(Matcher)一览

toBe 用于精确相等( Object.is ),但我们需要测试各种条件。Jest提供了丰富的匹配器。

匹配器 用途 示例
toBe 精确相等(适用于数字、字符串、布尔值等原始类型) expect(1 + 1).toBe(2)
toEqual 深度递归比较对象或数组的值 (最常用) expect({a:1}).toEqual({a:1})
toBeNull 只匹配 null expect(null).toBeNull()
toBeUndefined 只匹配 undefined expect(undefined).toBeUndefined()
toBeDefined toBeUndefined 相反 expect(‘value’).toBeDefined()
toBeTruthy 匹配任何在布尔上下文中为真的值 expect(1).toBeTruthy()
toBeFalsy 匹配任何在布尔上下文中为假的值 expect(0).toBeFalsy()
toBeGreaterThan 数字大于 expect(10).toBeGreaterThan(5)
toBeGreaterThanOrEqual 数字大于等于 expect(10).toBeGreaterThanOrEqual(10)
toBeLessThan 数字小于 expect(5).toBeLessThan(10)
toBeCloseTo 浮点数近似相等,避免精度问题 expect(0.1+0.2).toBeCloseTo(0.3)
toMatch 字符串匹配正则表达式 expect(‘team’).toMatch(/t.m/)
toContain 数组或可迭代对象包含某元素 expect([1,2,3]).toContain(2)
toThrow 函数调用时抛出错误 expect(()=>{throw Error()}).toThrow()

重点区分 toBe toEqual : 这是新手最容易混淆的地方。 toBe 检查的是 引用是否相同 (类似于 === ),对于对象和数组,即使内容一样,引用不同也会失败。而 toEqual 会递归检查每个字段的值是否相等。

const obj1 = { a: 1 };
const obj2 = { a: 1 };
const obj3 = obj1;

expect(obj1).toBe(obj3); // 通过,是同一个引用
expect(obj1).toBe(obj2); // 失败!内容相同,但不是同一个对象
expect(obj1).toEqual(obj2); // 通过,值深度相等

在测试中, 对于对象和数组,99%的情况你应该使用 toEqual

4.3 测试异步代码

现代JavaScript离不开异步操作。Jest提供了多种优雅的方式来测试异步代码。

1. 使用 async/await (推荐) 这是最清晰的方式。只需在测试函数前加上 async 关键字,然后 await 异步操作即可。

假设我们有一个异步函数 fetchData ,它返回一个Promise。

// asyncFunctions.js
function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => resolve('peanut butter'), 100);
  });
}

module.exports = { fetchData };

测试文件:

// asyncFunctions.test.js
const { fetchData } = require('./asyncFunctions');

test('the data is peanut butter', async () => {
  const data = await fetchData();
  expect(data).toBe('peanut butter');
});

2. 使用 .resolves / .rejects 匹配器 这种方式让你可以直接在 expect 语句中处理Promise,无需 async/await

test('the data is peanut butter with resolves', () => {
  // 注意:这里必须 return 这个 Promise,Jest会等待它解决
  return expect(fetchData()).resolves.toBe('peanut butter');
});

// 测试异步错误
function fetchDataWithError() {
  return Promise.reject('error');
}
test('the fetch fails with an error', () => {
  return expect(fetchDataWithError()).rejects.toMatch('error');
});

注意事项 :当你测试返回Promise的函数时, 必须确保Promise被返回给Jest 。如果你使用了 async/await ,Jest会自动处理。如果你直接返回一个 expect(...).resolves 的Promise,也必须用 return 。否则,Jest可能在Promise解决前就结束测试,导致测试误通过。

4.4 模拟(Mock)函数与模块

单元测试的核心是“隔离”。我们想测试函数A,但函数A内部调用了函数B。为了不让函数B的错误影响对A的测试,我们需要“模拟”函数B的行为。这就是Mock的用武之地。Jest的Mock功能极其强大。

模拟一个函数:

// 创建一个模拟函数
const mockCallback = jest.fn();

// 模拟函数可以配置返回值
mockCallback.mockReturnValueOnce(10).mockReturnValueOnce('x').mockReturnValue(true);

// 在测试中使用它
test('mock function', () => {
  expect(mockCallback()).toBe(10);
  expect(mockCallback()).toBe('x');
  expect(mockCallback()).toBe(true);
  expect(mockCallback()).toBe(true); // 之后一直返回 true

  // 还可以检查模拟函数是如何被调用的
  expect(mockCallback).toHaveBeenCalledTimes(4); // 被调用了4次
});

模拟整个模块: 这是更常见的场景。假设我们有一个工具模块 utils.js ,它里面有一个发送网络请求的函数 request ,我们不想在测试中真的发送请求。

// utils.js
function request() {
  // 真实的网络请求,很慢且有副作用
  return fetch('...');
}
module.exports = { request };

// service.js (我们要测试这个)
const { request } = require('./utils');
function getUser() {
  return request().then(data => data.user);
}
module.exports = { getUser };

在测试 getUser 时,我们想模拟掉 utils.request

// service.test.js
// 1. 在文件顶部模拟整个 utils 模块
jest.mock('./utils');

const { getUser } = require('./service');
const { request } = require('./utils'); // 注意:这里拿到的是已经被Jest自动创建的模拟函数

test('getUser returns user data', async () => {
  // 2. 设置模拟函数的返回值
  request.mockResolvedValue({ user: 'John Doe' });

  // 3. 执行测试
  const user = await getUser();

  // 4. 断言结果
  expect(user).toBe('John Doe');
  // 5. 断言模拟函数被正确调用
  expect(request).toHaveBeenCalledTimes(1);
});

通过 jest.mock(‘./utils’) ,Jest会自动用模拟函数替换 utils 模块的所有导出。这样, service.js 中引入的 request 就是一个我们可以控制的模拟函数,不会发出真实请求。

Mock是单元测试中高级但必备的技能,它能让你将测试目标完全隔离出来。

5. 进阶配置与最佳实践

掌握了基础用法后,一些配置和最佳实践能让你的测试更高效、更健壮。

5.1 配置文件(jest.config.js)常用选项

虽然Jest可以零配置运行,但通过配置文件可以定制化很多行为。在项目根目录创建 jest.config.js 文件。

// jest.config.js
module.exports = {
  // 在每个测试文件执行之前,运行一些代码来设置测试环境(如配置jsdom)
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],

  // 测试环境。默认为'node',测试前端代码时可设为'jsdom'以模拟浏览器环境
  testEnvironment: 'jsdom',

  // 告诉Jest需要匹配哪些文件
  testMatch: [
    '**/__tests__/**/*.[jt]s?(x)',
    '**/?(*.)+(spec|test).[jt]s?(x)'
  ],

  // 忽略某些路径
  testPathIgnorePatterns: ['/node_modules/', '/dist/'],

  // 收集测试覆盖率信息
  collectCoverage: true,
  coverageDirectory: 'coverage',
  collectCoverageFrom: [
    'src/**/*.{js,jsx}',
    '!src/**/*.d.ts',
    '!src/index.js',
  ],
};
  • setupFilesAfterEnv :非常有用。你可以在这里面全局引入测试库(如 @testing-library/jest-dom 来扩展匹配器),或者设置一些全局的Mock。
  • testEnvironment: ‘jsdom’ :如果你想测试涉及 document , window 等浏览器API的前端代码,这是必须的。
  • collectCoverage :开启覆盖率报告,可以直观地看到有多少代码被测试覆盖了。

5.2 测试驱动开发(TDD)快速体验

TDD是一种先写测试,再写实现代码的开发模式。它的节奏通常是“红-绿-重构”。

  1. :写一个失败的测试。此时功能还没实现,测试自然是红的。
  2. 绿 :用最简单、最快速的方式编写代码,让测试通过。
  3. 重构 :在测试的保护下,优化代码结构,消除重复,提高可读性。

我们用TDD来实现一个简单的 capitalize 函数(将字符串首字母大写)。

步骤1:红 创建 stringUtils.test.js ,先写测试。

const { capitalize } = require('./stringUtils');

test('capitalizes the first letter of a string', () => {
  expect(capitalize('hello')).toBe('Hello');
  expect(capitalize('world')).toBe('World');
});

运行 npm test ,测试失败,因为 stringUtils.js 还不存在。这是预期的“红”。

步骤2:绿 创建 stringUtils.js ,用最简单的方式实现。

function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

module.exports = { capitalize };

再次运行测试,变“绿”了。

步骤3:重构 审视我们的代码,目前很简单,可能不需要重构。但如果未来需求变更(比如要处理空字符串),我们可以在测试的保护下安全地修改。

TDD强迫你从使用者的角度思考接口,并且天然地保证了高测试覆盖率。对于逻辑清晰的工具函数或核心业务逻辑,强烈推荐尝试TDD。

5.3 组织测试代码的实用技巧

  • 描述要清晰具体 test(‘works’) 是糟糕的描述, test(‘returns null when input is empty string’) 是好的描述。失败时一目了然。
  • 一个测试,一个断言 :理想情况下,一个测试用例只验证一件事。这能让测试更清晰,也更容易定位问题。但这并非铁律,有时多个相关的断言放在一个测试里也是可以的,关键是逻辑要紧密相关。
  • 使用 beforeEach afterEach :如果多个测试需要相同的设置(如初始化一个对象、连接数据库)和清理工作,可以使用这些钩子函数,避免代码重复。
describe('database operations', () => {
  let dbConnection;

  beforeEach(() => {
    // 在每个测试开始前,建立数据库连接
    dbConnection = createConnection();
  });

  afterEach(() => {
    // 在每个测试结束后,关闭连接
    dbConnection.close();
  });

  test('query user by id', () => {
    // 这里可以直接使用 dbConnection
    const user = dbConnection.query('SELECT * FROM users WHERE id = 1');
    expect(user.name).toBe('Alice');
  });

  test('insert a new user', () => {
    // 另一个测试,同样有可用的 dbConnection
    // ...
  });
});
  • 测试文件放在哪里? 两种主流方式:
    1. 与源码并列 src/math.js 对应 src/math.test.js 。优点是导入路径短,结构清晰。
    2. 集中放在 __tests__ 目录 :如 src/__tests__/math.test.js 。优点是测试文件与源码分离,不会干扰项目结构。 根据团队习惯选择即可,Jest都支持。

6. 常见问题与排查技巧实录

在实际使用中,你肯定会遇到各种问题。这里记录了一些高频问题和我的解决思路。

6.1 “Cannot use import statement outside a module”

问题 :你在测试文件中使用了ES6的 import 语法,但Jest报错说不支持。

原因 :Node.js默认使用CommonJS模块系统。Jest运行在Node.js上,虽然它内部能处理ESM,但需要明确配置。

解决方案

  1. 确保 package.json 中包含 ”type”: “module” 。这告诉Node.js将 .js 文件视为ES模块。
  2. 如果项目是混合模块(既有ESM又有CommonJS),或者你不想设置 ”type”: “module” ,则需要通过Babel来转译。安装必要的包:
    npm install --save-dev babel-jest @babel/core @babel/preset-env
    
  3. 创建 babel.config.js 文件:
    module.exports = {
      presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
    };
    
  4. Jest会自动检测到Babel配置并使用它来转译代码, import 语法就可以正常工作了。

6.2 测试涉及DOM操作的前端代码报错

问题 :测试一个操作 document.getElementById 的函数时,报错 document is not defined

原因 :Jest默认的测试环境是Node.js,没有浏览器里的 document window 对象。

解决方案

  1. jest.config.js 中设置 testEnvironment: ‘jsdom’ jsdom 是一个在Node.js中模拟浏览器DOM环境的库,Jest集成了它。
  2. 如果使用了像 @testing-library/jest-dom 这样的库来扩展匹配器(如 toBeInTheDocument ),需要在 jest.setup.js 文件中引入:
    // jest.setup.js
    import '@testing-library/jest-dom';
    
    并在 jest.config.js setupFilesAfterEnv 中配置这个文件。

6.3 Mock不生效或行为不符合预期

问题 :明明用 jest.mock() 模拟了模块,但测试中调用的似乎还是原始模块。

原因与排查

  1. 作用域问题 jest.mock() 调用会被提升到文件顶部执行。确保它在所有 import 语句之前(Jest会自动处理,但如果你在测试函数内部调用 jest.mock 是无效的)。
  2. 路径问题 jest.mock(‘./module’) 中的路径必须是待测文件 import require 该模块时使用的 完全相同 的路径。大小写和相对路径都要一致。
  3. 手动Mock与自动Mock jest.mock(‘./module’) 会使用Jest自动生成的模拟(所有函数都是返回 undefined 的Jest Mock函数)。如果你需要更复杂的模拟行为,可以在与模块同级的 __mocks__ 目录下创建手动Mock文件。
    • 例如,要模拟 fs 模块,创建 __mocks__/fs.js
    • 然后在测试文件中写 jest.mock(‘fs’) ,Jest就会优先使用你手动创建的Mock。

6.4 异步测试超时或未等待完成

问题 :异步测试有时会误通过(没有等到Promise解决就结束),或者因超时而失败。

排查与解决

  1. 确保返回Promise :如果你的测试不包含 async 关键字,那么必须在 expect 语句前 return 那个Promise。
    // 正确
    test(‘async test‘, () => {
      return fetchData().then(data => {
        expect(data).toBe(‘...‘);
      });
    });
    // 错误(可能误通过)
    test(‘async test‘, () => {
      fetchData().then(data => {
        expect(data).toBe(‘...‘); // 这个断言可能来不及执行
      });
    });
    
  2. 使用 async/await :这是最不容易出错的方式,清晰易懂。
  3. 调整超时时间 :默认超时是5秒。如果异步操作很慢,可以在测试用例或 describe 块中单独设置:
    test(‘slow test‘, async () => {
      // ... 慢速操作
    }, 10000); // 设置10秒超时
    

6.5 测试覆盖率报告解读

运行 npm test -- --coverage 或在配置中开启 collectCoverage 后,会生成覆盖率报告。

报告中主要看四个指标:

  • Statements(语句覆盖率) :有多少比例的代码语句被执行了。
  • Branches(分支覆盖率) :有多少比例的控制分支(如if/else)被执行了。 这个指标最重要 ,因为它能发现未测试的条件逻辑。
  • Functions(函数覆盖率) :有多少比例的函数被调用了。
  • Lines(行覆盖率) :有多少比例的代码行被执行了。

不要盲目追求100%的覆盖率,这通常不切实际且性价比低。应该 重点关注核心业务逻辑和复杂分支的覆盖 。覆盖率报告是一个发现测试盲点的好工具,而不是一个必须达成的KPI。

最后,记住测试的初衷是提升代码质量和开发效率,而不是增加负担。从简单的工具函数开始写起,逐渐培养“测试思维”,你会发现自己对代码的理解更深了,改起代码来也更有底气了。Jest就是这个过程中最得力的伙伴。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值