Jest 安装与配置 #

安装 Jest #

基本安装 #

bash
# 使用 npm
npm install --save-dev jest

# 使用 yarn
yarn add --dev jest

# 使用 pnpm
pnpm add --save-dev jest

版本选择 #

bash
# 安装最新版本
npm install --save-dev jest@latest

# 安装指定版本
npm install --save-dev jest@29.7.0

# 安装下一个版本
npm install --save-dev jest@next

快速开始 #

创建第一个测试 #

bash
# 创建项目目录
mkdir my-jest-project
cd my-jest-project

# 初始化项目
npm init -y

# 安装 Jest
npm install --save-dev jest

创建源文件:

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

module.exports = sum;

创建测试文件:

javascript
// sum.test.js
const sum = require('./sum');

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

运行测试 #

bash
# 直接运行
npx jest

# 添加到 package.json
{
  "scripts": {
    "test": "jest"
  }
}

# 然后运行
npm test

测试输出 #

text
PASS  ./sum.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.5 s

配置 Jest #

配置方式 #

Jest 支持三种配置方式:

1. package.json #

json
{
  "jest": {
    "testEnvironment": "node",
    "testMatch": ["**/*.test.js"],
    "collectCoverage": true,
    "coverageDirectory": "coverage"
  }
}

2. jest.config.js #

javascript
module.exports = {
  testEnvironment: 'node',
  testMatch: ['**/*.test.js'],
  collectCoverage: true,
  coverageDirectory: 'coverage',
  verbose: true,
};

3. jest.config.ts #

typescript
import type { Config } from 'jest';

const config: Config = {
  testEnvironment: 'node',
  testMatch: ['**/*.test.ts'],
  collectCoverage: true,
  coverageDirectory: 'coverage',
};

export default config;

核心配置选项 #

测试环境 #

javascript
module.exports = {
  // jsdom - 浏览器环境(默认)
  testEnvironment: 'jsdom',
  
  // node - Node.js 环境
  testEnvironment: 'node',
  
  // 自定义环境
  testEnvironment: './custom-environment.js',
};

测试文件匹配 #

javascript
module.exports = {
  // 默认匹配模式
  testMatch: [
    '**/__tests__/**/*.[jt]s?(x)',
    '**/?(*.)+(spec|test).[jt]s?(x)'
  ],
  
  // 自定义匹配
  testMatch: [
    '**/*.test.js',
    '**/*.spec.js'
  ],
  
  // 忽略文件
  testPathIgnorePatterns: [
    '/node_modules/',
    '/dist/'
  ],
};

模块解析 #

javascript
module.exports = {
  // 模块路径别名
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '^@components/(.*)$': '<rootDir>/src/components/$1',
    '^@utils/(.*)$': '<rootDir>/src/utils/$1',
    
    // CSS 模块 Mock
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
    
    // 静态资源 Mock
    '\\.(jpg|jpeg|png|gif|svg)$': '<rootDir>/__mocks__/fileMock.js',
  },
  
  // 模块目录
  modulePaths: ['<rootDir>/src'],
};

覆盖率配置 #

javascript
module.exports = {
  // 收集覆盖率
  collectCoverage: true,
  
  // 覆盖率目录
  coverageDirectory: 'coverage',
  
  // 收集文件
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
    '!src/index.js',
    '!**/node_modules/**',
  ],
  
  // 覆盖率阈值
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80,
    },
  },
  
  // 覆盖率报告格式
  coverageReporters: ['text', 'lcov', 'html'],
};

转换配置 #

javascript
module.exports = {
  // 转换器
  transform: {
    '^.+\\.jsx?$': 'babel-jest',
    '^.+\\.tsx?$': 'ts-jest',
  },
  
  // 忽略转换
  transformIgnorePatterns: [
    'node_modules/(?!(module-to-transform)/)',
  ],
};

TypeScript 支持 #

安装依赖 #

bash
npm install --save-dev typescript ts-jest @types/jest

配置 tsconfig.json #

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "types": ["jest", "node"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

配置 Jest for TypeScript #

javascript
// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  roots: ['<rootDir>/src'],
  testMatch: ['**/*.test.ts'],
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};

TypeScript 测试示例 #

typescript
// src/calculator.ts
export function add(a: number, b: number): number {
  return a + b;
}

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

// src/calculator.test.ts
import { add, subtract } from './calculator';

describe('Calculator', () => {
  test('adds two numbers', () => {
    expect(add(1, 2)).toBe(3);
  });

  test('subtracts two numbers', () => {
    expect(subtract(5, 3)).toBe(2);
  });
});

ts-jest 配置选项 #

javascript
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  globals: {
    'ts-jest': {
      tsconfig: 'tsconfig.json',
      isolatedModules: true,
    },
  },
};

Babel 配置 #

安装依赖 #

bash
npm install --save-dev babel-jest @babel/core @babel/preset-env

配置 babel.config.js #

javascript
module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { node: 'current' } }],
  ],
};

支持 JSX #

bash
npm install --save-dev @babel/preset-react
javascript
module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { node: 'current' } }],
    '@babel/preset-react',
  ],
};

支持 TypeScript #

bash
npm install --save-dev @babel/preset-typescript
javascript
module.exports = {
  presets: [
    ['@babel/preset-env', { targets: { node: 'current' } }],
    '@babel/preset-react',
    '@babel/preset-typescript',
  ],
};

React 项目配置 #

Create React App #

Create React App 内置 Jest,无需额外配置:

bash
# 创建项目
npx create-react-app my-app

# 运行测试
npm test

手动配置 React 项目 #

bash
npm install --save-dev jest @testing-library/react @testing-library/jest-dom jsdom
javascript
// jest.config.js
module.exports = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
  },
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
  },
};
javascript
// jest.setup.js
import '@testing-library/jest-dom';

Vue 项目配置 #

Vue CLI #

bash
# 创建项目时选择 Jest
vue create my-project

# 或添加 Jest
vue add unit-jest

手动配置 Vue 项目 #

bash
npm install --save-dev jest @vue/test-utils vue-jest @vue/vue3-jest
javascript
// jest.config.js
module.exports = {
  testEnvironment: 'jsdom',
  transform: {
    '^.+\\.vue$': '@vue/vue3-jest',
    '^.+\\.js$': 'babel-jest',
  },
  moduleFileExtensions: ['vue', 'js', 'json'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
  },
};

Node.js 项目配置 #

javascript
// jest.config.js
module.exports = {
  testEnvironment: 'node',
  testMatch: ['**/*.test.js'],
  collectCoverageFrom: ['src/**/*.js'],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
    },
  },
};

完整配置示例 #

javascript
// jest.config.js
module.exports = {
  // 根目录
  rootDir: './',
  
  // 测试环境
  testEnvironment: 'jsdom',
  
  // 测试文件匹配
  testMatch: [
    '<rootDir>/src/**/*.test.{js,jsx,ts,tsx}',
    '<rootDir>/src/**/*.spec.{js,jsx,ts,tsx}',
  ],
  
  // 忽略路径
  testPathIgnorePatterns: [
    '/node_modules/',
    '/dist/',
    '/coverage/',
  ],
  
  // 模块文件扩展名
  moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'],
  
  // 模块路径别名
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '^@components/(.*)$': '<rootDir>/src/components/$1',
    '^@utils/(.*)$': '<rootDir>/src/utils/$1',
    '^@hooks/(.*)$': '<rootDir>/src/hooks/$1',
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
    '\\.(jpg|jpeg|png|gif|svg|webp)$': '<rootDir>/__mocks__/fileMock.js',
  },
  
  // 转换
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
  },
  
  // 忽略转换
  transformIgnorePatterns: [
    'node_modules/(?!(react-router-dom|axios)/)',
  ],
  
  // 设置文件
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  
  // 覆盖率
  collectCoverage: false,
  coverageDirectory: 'coverage',
  collectCoverageFrom: [
    'src/**/*.{js,jsx,ts,tsx}',
    '!src/**/*.d.ts',
    '!src/index.{js,jsx,ts,tsx}',
    '!src/**/index.{js,jsx,ts,tsx}',
    '!**/node_modules/**',
  ],
  coverageThreshold: {
    global: {
      branches: 70,
      functions: 70,
      lines: 70,
      statements: 70,
    },
  },
  coverageReporters: ['text', 'text-summary', 'lcov', 'html'],
  
  // 全局变量
  globals: {
    'ts-jest': {
      isolatedModules: true,
    },
  },
  
  // 监听插件
  watchPlugins: [
    'jest-watch-typeahead/filename',
    'jest-watch-typeahead/testname',
  ],
  
  // 详细输出
  verbose: true,
  
  // 并行执行
  maxWorkers: '50%',
  
  // 超时时间
  testTimeout: 10000,
};

命令行选项 #

常用命令 #

bash
# 运行所有测试
jest

# 运行指定文件
jest sum.test.js

# 运行匹配模式的测试
jest --testNamePattern="add"

# 监听模式
jest --watch

# 只运行相关测试
jest --onlyChanged

# 生成覆盖率
jest --coverage

# 并行执行
jest --maxWorkers=4

# 串行执行
jest --runInBand

# 更新快照
jest --updateSnapshot

# 清除缓存
jest --clearCache

# 显示详细输出
jest --verbose

# 静默模式
jest --silent

package.json scripts #

json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "test:ci": "jest --ci --coverage --maxWorkers=2",
    "test:changed": "jest --onlyChanged",
    "test:update": "jest --updateSnapshot"
  }
}

下一步 #

现在你已经完成了 Jest 的安装和配置,接下来学习 基础测试 开始编写测试!

最后更新:2026-03-28