HelloWorld Jest 集成教程

把 Jest 集成到 HelloWorld 项目,关键是把测试目标弄清楚、装好依赖、处理转译(Babel 或 TypeScript)、配置测试运行脚本与覆盖率,然后在 CI 环境里稳定运行。下面按实操步骤来,从零开始安装、写第一个测试、处理常见模块与静态资源问题、到进阶的快照、异步测试和覆盖率配置,让你能边学边试,立刻看到效果。

HelloWorld Jest 集成教程

HelloWorld Jest 集成教程

为什么要在 HelloWorld 项目里用 Jest?

想象一下,代码像是一列火车,测试就是每节车厢的安全检查。Jest 提供断言、模拟、快照与覆盖率工具,让你在改动后能快速确认行为没变。它启动快、默认配置友好,社区插件多,适合前端(React、Vue)和 Node 工程。

开始前的准备

  • 确保项目能用 npm 或 yarn 安装依赖。
  • 知道项目语言:纯 JavaScript、Babel 转译、还是 TypeScript。
  • 决定运行环境:本地测试还是 CI(GitHub Actions、GitLab CI、Jenkins 等)。

安装 Jest(基础)

先在项目根目录执行安装命令。下面给出常用两种包管理器的写法:

npm npm install –save-dev jest
yarn yarn add –dev jest

然后在 package.json 的 scripts 里加一条:

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

第一步:写第一个测试文件

在项目中新建 __tests__/hello.test.js:

const sayHello = require('../src/sayHello');

test('sayHello 返回 Hello, World!', () => { expect(sayHello()).toBe('Hello, World!'); });

再写实现文件 src/sayHello.js:

module.exports = function() {
  return 'Hello, World!';
};

运行 npm test,你应该看到绿色通过信息。

Babel 支持(如果你使用 ESModules 或现代语法)

如果代码用到了 import/export、class fields、optional chaining 等语法,需要 Babel 给 Jest 转译。步骤:

  • 安装 Babel 相关依赖:
npm install --save-dev @babel/core @babel/preset-env babel-jest
  • 在项目根目录创建 .babelrcbabel.config.js,例如:
{
  "presets": ["@babel/preset-env"]
}

Jest 会自动使用 babel-jest 来转译,通常无需额外配置。如果你用 TypeScript,下面有专门一节。

TypeScript 支持

用 TypeScript 的话,可以选择两个常见方案:

  • 用 ts-jest 直接在测试时转译 TypeScript。
  • 先用 tsc 编译到 JavaScript,再对输出运行 Jest(不太方便)。

推荐方案:ts-jest,安装并配置:

npm install --save-dev ts-jest @types/jest typescript
npx ts-jest config:init

这会在项目根创建 jest.config.js,里面包含 TypeScript 的 transform 配置。然后把测试文件用 .ts/.tsx 写就可以了。

React 项目:处理 JSX 与组件快照

React 项目常配合 react-test-renderer@testing-library/react

npm install --save-dev @testing-library/react react-test-renderer

示例快照测试:

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

test('MyButton 快照', () => { const tree = renderer.create().toJSON(); expect(tree).toMatchSnapshot(); });

运行时,Jest 会在 __snapshots__ 文件夹生成快照文件,方便后续对比。

常见配置项速查(jest.config.js 模板)

module.exports = {
  testEnvironment: 'node', // 或 'jsdom' 用于浏览器环境
  transform: {
    '^.+\\.(js|jsx)$': 'babel-jest', // 或 ts-jest
  },
  moduleNameMapper: {
    '\\.(css|less|scss)$': 'identity-obj-proxy', // 静态资源/样式 mock
  },
  collectCoverage: true,
  coverageDirectory: 'coverage',
  testPathIgnorePatterns: ['/node_modules/', '/dist/'],
};

处理静态资源与模块别名

前端项目常遇到导入图片、样式或用到 webpack 别名。Jest 需要知道如何 mock 或解析:

  • 样式文件:安装 identity-obj-proxy 并在 moduleNameMapper 中映射为 ‘identity-obj-proxy’。
  • 图片等二进制资源:映射到一个空模块(比如 __mocks__/fileMock.js),内容导出字符串或空对象。
  • 模块别名:把 webpack 的别名映射到 Jest 的 moduleNameMapper。

异步测试与定时器

异步函数可以用 async/await、done 回调或返回 Promise 来测试。例子:

test('异步请求返回数据', async () => {
  const data = await fetchData();
  expect(data.id).toBe(42);
});

如果你用到定时器(setTimeout、setInterval),Jest 提供假定时器:jest.useFakeTimers(),这样能快速推进时间并断言行为。

Mock(模拟)技巧

模拟是 Jest 的强项,可以把外部依赖替换成可控版本:

  • jest.fn() 创建一个可监视的空函数。
  • jest.spyOn(obj, ‘method’) 监视对象方法,必要时可 mock 实现。
  • jest.mock(‘moduleName’) 可以把整个模块替换成 mocks 目录下的实现。

常见用法是把网络请求、文件系统、第三方 SDK mock 掉,保证测试稳定且速度快。

覆盖率(Coverage)与阈值

开启覆盖率很简单:npm test — –coverage 或在 jest.config.js 设 collectCoverage: true。推荐设定阈值,避免“覆盖率幻觉”:

coverageThreshold: {
  global: {
    branches: 80,
    functions: 85,
    lines: 90,
    statements: 90,
  },
},

这样当覆盖率下降时 CI 会失败,提醒你补充测试。

在 CI 中运行 Jest(以 GitHub Actions 为例)

把测试加到持续集成是必须的。简单的工作流步骤:

  • checkout 代码;
  • 安装依赖(npm ci 或 yarn install –frozen-lockfile);
  • 运行构建步骤(如果需要转译);
  • 执行 npm test — –ci –reporters=default –reporters=jest-junit(可选输出 junit)。

CI 环境常见问题包括内存不足与并发限制,必要时用 –runInBand 或调整 maxWorkers。

调试与常见问题排查

下面是一些典型问题与处理思路:

  • 测试跑不起来,语法错误:检查 jest transform 是否针对目标文件配置正确(Babel/ts-jest)。
  • 模块找不到:确认 moduleNameMapper 覆盖了别名与静态资源映射。
  • 快照意外变更:先阅读差异,确认是合理变更再更新快照(jest -u),不要盲目更新。
  • 测试在 CI 中超时或内存溢出:用 –runInBand、减少并发或提高机器规格。

一张速查表:常用命令

运行所有测试 npm test
带覆盖率运行 npm test — –coverage
只运行匹配文件 npm test — -t “关键字”
更新快照 npm test — -u

进阶用法与优化点

  • 并行与工作线程:默认 Jest 会并行运行测试以提高速度,必要时调整 maxWorkers。
  • 测试分片:大型项目可在 CI 中按文件或目录分片运行以缩短总时长。
  • 自定义环境:如果 testEnvironment 默认的 node/jsdom 不够,可实现自定义环境扩展。
  • 报告集成:把 coverage 输出、jest-junit 等集成到 CI 中,方便看报表。

写测试的小建议(实践中的心得)

  • 先写最小可重现的测试:一个小函数的单元测试比复杂场景更容易定位问题。
  • 把外部依赖隔离:网络请求、时间和随机数都应当 mock,保证测试稳定。
  • 保持测试可读:像写文档一样命名测试,别人能从测试名看出期望行为。
  • 不要把测试当成覆盖率游戏:高覆盖率是手段,不是目的,关键是捕捉真实风险。

好了,按上面步骤去做,你会先看到测试跑通,然后逐步完善配置(Babel/TypeScript、模块映射、CI 集成)。过程中如果遇到某个特定报错,常常是 transform 或 moduleNameMapper 配置不到位,按错误信息定位文件路径和 loader 配置,多试几次就能摸清楚。写到这儿,差不多把从零开始到进阶的常见场景都覆盖了,接下来就动手实践一次,边做边调,几次迭代后你会发现测试给项目带来的信心和节奏感。