配置 Jest
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
Jest 的设计理念是默认开箱即用,但有时您需要更多配置能力。
建议在专用的 JavaScript、TypeScript 或 JSON 文件中定义配置。若文件命名为 jest.config.js|ts|mjs|cjs|cts|json,Jest 将自动发现该文件。您可以使用 --config 参数显式指定文件路径。
请注意:最终生成的配置对象必须始终支持 JSON 序列化。
配置文件应直接导出一个对象:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
verbose: true,
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
verbose: true,
};
export default config;
或导出一个返回对象的函数:
- JavaScript
- TypeScript
/** @returns {Promise<import('jest').Config>} */
module.exports = async () => {
return {
verbose: true,
};
};
import type {Config} from 'jest';
export default async (): Promise<Config> => {
return {
verbose: true,
};
};
Jest 默认需要 ts-node 来读取 TypeScript 配置文件。您可以通过在文件顶部添加 @jest-config-loader 文档块来覆盖此行为。目前支持 ts-node 和 esbuild-register。请确保已安装 ts-node 或您指定的加载器。
/** @jest-config-loader ts-node */
// or
/** @jest-config-loader esbuild-register */
import type {Config} from 'jest';
const config: Config = {
verbose: true,
};
export default config;
您还可以向加载器传递选项,例如启用 transpileOnly:
/** @jest-config-loader ts-node */
/** @jest-config-loader-options {"transpileOnly": true} */
import type {Config} from 'jest';
const config: Config = {
verbose: true,
};
export default config;
配置也可作为普通对象存储在 JSON 文件中:
{
"bail": 1,
"verbose": true
}
或者通过项目 package.json 中的 "jest" 字段定义配置:
{
"name": "my-project",
"jest": {
"verbose": true
}
}
也可通过项目 package.json 中的 "jest" 字段引用 Jest 的 JSON 配置文件:
{
"name": "my-project",
"jest": "./path/to/config.json"
}
选项说明
您可以从 jest-config 获取 Jest 的默认配置进行扩展:
- JavaScript
- TypeScript
const {defaults} = require('jest-config');
/** @type {import('jest').Config} */
const config = {
moduleDirectories: [...defaults.moduleDirectories, 'bower_components'],
};
module.exports = config;
import type {Config} from 'jest';
import {defaults} from 'jest-config';
const config: Config = {
moduleDirectories: [...defaults.moduleDirectories, 'bower_components'],
};
export default config;
automock[布尔值]bail[数值 | 布尔值]cacheDirectory[字符串]clearMocks[布尔值]collectCoverage[布尔值]collectCoverageFrom[数组]coverageDirectory[字符串]coveragePathIgnorePatterns[数组<字符串>]coverageProvider[字符串]coverageReporters[数组<字符串 | [字符串, 选项]>]coverageThreshold[对象]dependencyExtractor[字符串]displayName[字符串, 对象]errorOnDeprecated[布尔值]extensionsToTreatAsEsm[数组<字符串>]fakeTimers[object]forceCoverageMatch[array<string>]globals[object]globalSetup[string]globalTeardown[string]haste[object]injectGlobals[boolean]maxConcurrency[number]maxWorkers[number | string]moduleDirectories[array<string>]moduleFileExtensions[array<string>]moduleNameMapper[object<string, string | array<string>>]modulePathIgnorePatterns[array<string>]modulePaths[array<string>]notify[boolean]notifyMode[string]openHandlesTimeout[数字]preset[字符串]prettierPath[字符串]projects[数组<string | ProjectConfig>]randomize[布尔值]reporters[数组<moduleName | [moduleName, options]>]resetMocks[布尔值]resetModules[布尔值]resolver[字符串]restoreMocks[布尔值]rootDir[字符串]roots[数组<字符串>]runtime[字符串]runner[字符串]sandboxInjectedGlobals[array<string>]setupFiles[array]setupFilesAfterEnv[array]showSeed[boolean]slowTestThreshold[number]snapshotFormat[对象]snapshotResolver[字符串]snapshotSerializers[字符串数组]testEnvironment[字符串]testEnvironmentOptions[对象]testFailureExitCode[数字]testMatch[字符串 | 数组<字符串>]testPathIgnorePatterns[array<string>]testRegex[string | array<string>]testResultsProcessor[string]testRunner[string]testSequencer[string]testTimeout[number]transform[object<string, pathToTransformer | [pathToTransformer, object]>]transformIgnorePatterns[array<string>]unmockedModulePathPatterns[array<string>]verbose[boolean]waitForUnhandledRejections[boolean]watchPathIgnorePatterns[array<string>]watchPlugins[数组<string | [string, Object]>]watchman[布尔值]workerIdleMemoryLimit[数值 | 字符串]//[字符串]workerThreads
参数详解
automock [布尔值]
默认值:false
此选项告知 Jest 自动模拟测试中所有导入的模块。所有被使用的模块将被替换为模拟实现,同时保留原始 API 接口。
示例:
export default {
authorize: () => 'token',
isAuthorized: secret => secret === 'wizard',
};
import utils from '../utils';
test('if utils mocked automatically', () => {
// Public methods of `utils` are now mock functions
expect(utils.authorize.mock).toBeTruthy();
expect(utils.isAuthorized.mock).toBeTruthy();
// You can provide them with your own implementation
// or pass the expected return value
utils.authorize.mockReturnValue('mocked_token');
utils.isAuthorized.mockReturnValue(true);
expect(utils.authorize()).toBe('mocked_token');
expect(utils.isAuthorized('not_wizard')).toBeTruthy();
});
当存在手动模拟文件(如 __mocks__/lodash.js)时,Node 模块会自动被模拟。详见此处。
Node.js 核心模块(如 fs)默认不会被模拟。可通过显式调用模拟,例如 jest.mock('fs')。
bail [数值 | 布尔值]
默认值:0
默认情况下,Jest 会运行所有测试并在完成后将所有错误输出到控制台。使用此配置选项可使 Jest 在遇到 n 次失败后停止测试。将 bail 设为 true 等同于设为 1。
cacheDirectory [字符串]
默认值:"/tmp/<path>"
Jest 存储依赖缓存信息的目录。
Jest 会尝试预先扫描你的依赖树一次并将其缓存,以减少运行测试时可能发生的文件系统频繁操作。此配置选项允许你自定义 Jest 在磁盘上存储该缓存数据的位置。
clearMocks [布尔值]
默认值:false
在每次测试前自动清除模拟调用、实例、上下文和结果。等效于在每个测试前调用jest.clearAllMocks()。此操作不会移除已配置的任何模拟实现。
collectCoverage [布尔值]
默认值:false
指示在执行测试时是否应收集覆盖率信息。由于这会给所有执行的文件添加覆盖率收集语句,可能会显著降低测试速度。
Jest 内置两种覆盖率提供程序:babel(默认)和 v8。更多详情请参阅 coverageProvider 选项。
babel 和 v8 覆盖率提供程序分别使用 /* istanbul ignore next */ 和 /* c8 ignore next */ 注释从覆盖率报告中排除行。更多信息可查看 istanbuljs 文档 和 c8 文档。
collectCoverageFrom [数组]
默认: undefined
一个 glob 模式 数组,指示应收集覆盖率信息的文件集合。如果文件匹配指定的 glob 模式,即使该文件没有测试用例且从未在测试套件中被引用,也会收集其覆盖率信息。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
collectCoverageFrom: [
'**/*.{js,jsx}',
'!**/node_modules/**',
'!**/vendor/**',
],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
collectCoverageFrom: [
'**/*.{js,jsx}',
'!**/node_modules/**',
'!**/vendor/**',
],
};
export default config;
这将收集项目 rootDir 内所有文件的覆盖率信息,除了匹配 **/node_modules/** 或 **/vendor/** 的文件。
每个 glob 模式按配置中的顺序应用。例如 ["!**/__tests__/**", "**/*.js"] 不会排除 __tests__,因为第二个模式覆盖了否定规则。要使否定 glob 生效,在此示例中必须将其置于 **/*.js 之后。
此选项要求 collectCoverage 设为 true 或使用 --coverage 参数调用 Jest。
Help:
If you are seeing coverage output such as...
=============================== Coverage summary ===============================
Statements : Unknown% ( 0/0 )
Branches : Unknown% ( 0/0 )
Functions : Unknown% ( 0/0 )
Lines : Unknown% ( 0/0 )
================================================================================
Jest: Coverage data for global was not found.
Most likely your glob patterns are not matching any files. Refer to the micromatch documentation to ensure your globs are compatible.
coverageDirectory [字符串]
默认: undefined
Jest输出覆盖率文件的目录路径。
coveragePathIgnorePatterns [数组<字符串>]
默认值:["/node_modules/"]
一个正则表达式模式字符串数组,在执行测试前与所有文件路径进行匹配。如果文件路径匹配任何模式,将跳过覆盖率信息收集。
这些模式字符串会匹配完整路径。使用 <rootDir> 字符串标记可包含项目根目录路径,防止在不同环境下因根目录不同而意外忽略所有文件。例如:["<rootDir>/build/", "<rootDir>/node_modules/"]。
coverageProvider [字符串]
指定用于检测代码覆盖率的提供程序。允许值为babel(默认)或v8。
coverageReporters [数组<字符串 | [字符串, 选项]>]
默认值:["clover", "json", "lcov", "text"]
Jest 在生成覆盖率报告时使用的报告器名称列表。可以使用任何 istanbul 报告器。
设置此选项会覆盖默认值。添加 "text" 或 "text-summary" 可在控制台输出中查看覆盖率摘要。
可通过元组形式传递额外选项。例如,您可以隐藏所有完全覆盖文件的覆盖率报告行:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
coverageReporters: ['clover', 'json', 'lcov', ['text', {skipFull: true}]],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
coverageReporters: ['clover', 'json', 'lcov', ['text', {skipFull: true}]],
};
export default config;
有关选项对象结构的更多信息,请参考 类型定义 中的 CoverageReporterWithOptions 类型。
coverageThreshold [对象]
默认: undefined
用于配置覆盖率结果的最低强制阈值。阈值可指定为 global(全局)、glob 模式 或目录/文件路径。若未达到阈值,Jest 将执行失败。正数阈值表示要求的最低百分比,负数阈值表示允许的最大未覆盖实体数。
例如,使用以下配置时,如果分支/行/函数覆盖率低于 80% 或存在超过 10 个未覆盖语句,Jest 将失败:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: -10,
},
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: -10,
},
},
};
export default config;
若同时指定了 glob/路径 和 global,则匹配路径的覆盖率数据将从全局统计中扣除,阈值将独立应用。glob 的阈值适用于所有匹配文件。若路径指定的文件不存在,将返回错误。
例如,对于以下配置:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
coverageThreshold: {
global: {
branches: 50,
functions: 50,
lines: 50,
statements: 50,
},
'./src/components/': {
branches: 40,
statements: 40,
},
'./src/reducers/**/*.js': {
statements: 90,
},
'./src/api/very-important-module.js': {
branches: 100,
functions: 100,
lines: 100,
statements: 100,
},
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
coverageThreshold: {
global: {
branches: 50,
functions: 50,
lines: 50,
statements: 50,
},
'./src/components/': {
branches: 40,
statements: 40,
},
'./src/reducers/**/*.js': {
statements: 90,
},
'./src/api/very-important-module.js': {
branches: 100,
functions: 100,
lines: 100,
statements: 100,
},
},
};
export default config;
Jest 将在以下情况失败:
-
./src/components目录的分支或语句覆盖率低于 40% -
匹配
./src/reducers/**/*.jsglob 的文件存在语句覆盖率低于 90% -
./src/api/very-important-module.js文件覆盖率低于 100% -
其余文件合并覆盖率低于 50%(
global)
dependencyExtractor [字符串]
默认: undefined
此选项允许使用自定义依赖提取器。必须是导出包含 extract 函数的对象的 Node 模块,例如:
const crypto = require('crypto');
const fs = require('fs');
module.exports = {
extract(code, filePath, defaultExtract) {
const deps = defaultExtract(code, filePath);
// Scan the file and add dependencies in `deps` (which is a `Set`)
return deps;
},
getCacheKey() {
return crypto
.createHash('md5')
.update(fs.readFileSync(__filename))
.digest('hex');
},
};
extract 函数应返回包含代码中发现的依赖项的可迭代对象(Array、Set 等)。
该模块还可包含 getCacheKey 函数,用于生成缓存键以确定逻辑是否变更,从而决定是否应丢弃相关缓存产物。
displayName [字符串, 对象]
默认值:undefined
允许在测试运行时旁显示标签。这在多项目仓库中特别有用,可直观标识测试所属项目。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
displayName: 'CLIENT',
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
displayName: 'CLIENT',
};
export default config;
也可传递包含 name 和 color 属性的对象,用于自定义 displayName 的背景颜色。displayName 的值为字符串时默认为白色。Jest 使用 chalk 提供颜色支持,因此所有有效的 chalk 颜色选项均可使用。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
displayName: {
name: 'CLIENT',
color: 'blue',
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
displayName: {
name: 'CLIENT',
color: 'blue',
},
};
export default config;
errorOnDeprecated [布尔值]
默认值:false
使调用已弃用的 API 时抛出友好错误信息。有助于简化升级过程。
extensionsToTreatAsEsm [数组<字符串>]
默认值:[]
Jest 会将 .mjs 文件及最近的 package.json 中 type 字段设为 module 的 .js 文件作为 ECMAScript 模块执行。如需其他原生 ESM 文件支持,请在此指定其文件扩展名。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
extensionsToTreatAsEsm: ['.ts'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
extensionsToTreatAsEsm: ['.ts'],
};
export default config;
Jest 的 ESM 支持仍处于实验阶段,详情请参阅 相关文档。
fakeTimers [object]
默认值:{}
当代码设置了测试中无需等待的长超时时限时,伪计时器会非常有用。更多细节请参阅 伪计时器指南 和 API 文档。
此选项为所有测试提供伪计时器的默认配置。在测试文件中调用 jest.useFakeTimers() 将使用这些配置,若传入配置对象则会覆盖这些设置。例如,可配置 Jest 保留 process.nextTick() 的原始实现并调整递归计时器的执行上限:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
fakeTimers: {
doNotFake: ['nextTick'],
timerLimit: 1000,
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
fakeTimers: {
doNotFake: ['nextTick'],
timerLimit: 1000,
},
};
export default config;
// install fake timers for this file using the options from Jest configuration
jest.useFakeTimers();
test('increase the limit of recursive timers for this and following tests', () => {
jest.useFakeTimers({timerLimit: 5000});
// ...
});
无需在每个测试文件中单独调用 jest.useFakeTimers(),可通过 Jest 配置全局启用伪计时器:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
fakeTimers: {
enableGlobally: true,
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
fakeTimers: {
enableGlobally: true,
},
};
export default config;
配置选项:
type FakeableAPI =
| 'Date'
| 'hrtime'
| 'nextTick'
| 'performance'
| 'queueMicrotask'
| 'requestAnimationFrame'
| 'cancelAnimationFrame'
| 'requestIdleCallback'
| 'cancelIdleCallback'
| 'setImmediate'
| 'clearImmediate'
| 'setInterval'
| 'clearInterval'
| 'setTimeout'
| 'clearTimeout';
type ModernFakeTimersConfig = {
/**
* If set to `true` all timers will be advanced automatically by 20 milliseconds
* every 20 milliseconds. A custom time delta may be provided by passing a number.
* The default is `false`.
*/
advanceTimers?: boolean | number;
/**
* List of names of APIs that should not be faked. The default is `[]`, meaning
* all APIs are faked.
*/
doNotFake?: Array<FakeableAPI>;
/** Whether fake timers should be enabled for all test files. The default is `false`. */
enableGlobally?: boolean;
/**
* Use the old fake timers implementation instead of one backed by `@sinonjs/fake-timers`.
* The default is `false`.
*/
legacyFakeTimers?: boolean;
/** Sets current system time to be used by fake timers, in milliseconds. The default is `Date.now()`. */
now?: number;
/** Maximum number of recursive timers that will be run. The default is `100_000` timers. */
timerLimit?: number;
};
如需使用传统伪计时器实现(不支持额外选项),可通过以下方式全局启用:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
fakeTimers: {
enableGlobally: true,
legacyFakeTimers: true,
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
fakeTimers: {
enableGlobally: true,
legacyFakeTimers: true,
},
};
export default config;
forceCoverageMatch [array<string>]
默认值:['']
测试文件通常会被排除在代码覆盖率统计之外。此选项可覆盖该行为,将原本忽略的文件纳入统计。
例如,若测试文件使用 .t.js 扩展名:
export function sum(a, b) {
return a + b;
}
if (process.env.NODE_ENV === 'test') {
test('sum', () => {
expect(sum(1, 2)).toBe(3);
});
}
通过设置 forceCoverageMatch 即可收集这些文件的覆盖率数据:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
forceCoverageMatch: ['**/*.t.js'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
forceCoverageMatch: ['**/*.t.js'],
};
export default config;
globals [object]
默认值:{}
定义在所有测试环境中需可用的全局变量集合。
例如,以下配置将在所有测试环境中创建值为 true 的全局变量 __DEV__:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
globals: {
__DEV__: true,
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
globals: {
__DEV__: true,
},
};
export default config;
若在此指定引用类型值(如对象或数组),当测试运行期间代码修改该值时,此修改不会在其他测试文件中持久化。此外,globals 对象必须支持 JSON 序列化,因此不可用于声明全局函数,此类需求应通过 setupFiles 实现。
globalSetup [string]
默认: undefined
此选项允许使用自定义全局安装模块,该模块必须导出一个函数(可以是同步或异步)。该函数将在所有测试套件执行前触发一次,并接收两个参数:Jest 的 globalConfig 和 projectConfig。
在多项目运行器中配置的全局安装模块,仅当您运行该项目的至少一个测试时才会触发。
通过 globalSetup 定义的全局变量只能在 globalTeardown 中读取。您无法在测试套件中访问此处定义的全局变量。
虽然代码转换会应用于链接的安装文件,但 Jest 不会转换 node_modules 中的任何代码。这是因为需要加载实际的转换器(如 babel 或 typescript)来执行转换。
module.exports = async function (globalConfig, projectConfig) {
console.log(globalConfig.testPathPatterns);
console.log(projectConfig.cache);
// Set reference to mongod in order to close the server during teardown.
globalThis.__MONGOD__ = mongod;
};
module.exports = async function (globalConfig, projectConfig) {
console.log(globalConfig.testPathPatterns);
console.log(projectConfig.cache);
await globalThis.__MONGOD__.stop();
};
globalTeardown [string]
默认: undefined
此选项允许使用自定义全局拆卸模块,该模块必须导出一个函数(可以是同步或异步)。该函数将在所有测试套件执行后触发一次,并接收两个参数:Jest 的 globalConfig 和 projectConfig。
在多项目运行器中配置的全局拆卸模块,仅当您运行该项目的 至少一个测试时才会触发。
与 globalSetup 相同,关于 node_modules 转换的限制同样适用于 globalTeardown。
haste [object]
默认: undefined
此选项用于配置 jest-haste-map(Jest 内部文件爬虫/缓存系统)的行为。支持以下配置项:
type HasteConfig = {
/** Whether to hash files using SHA-1. */
computeSha1?: boolean;
/** The platform to use as the default, e.g. 'ios'. */
defaultPlatform?: string | null;
/** Force use of Node's `fs` APIs rather than shelling out to `find` */
forceNodeFilesystemAPI?: boolean;
/**
* Whether to follow symlinks when crawling for files.
* This options cannot be used in projects which use watchman.
* Projects with `watchman` set to true will error if this option is set to true.
*/
enableSymlinks?: boolean;
/** Path to a custom implementation of Haste. */
hasteImplModulePath?: string;
/** All platforms to target, e.g ['ios', 'android']. */
platforms?: Array<string>;
/** Whether to throw an error on module collision. */
throwOnModuleCollision?: boolean;
/** Custom HasteMap module */
hasteMapModulePath?: string;
/** Whether to retain all files, allowing e.g. search for tests in `node_modules`. */
retainAllFiles?: boolean;
};
injectGlobals [boolean]
默认值:true
将 Jest 的全局变量(expect、test、describe、beforeEach 等)注入全局环境。设为 false 时,需从 @jest/globals 显式导入,例如:
import {expect, jest, test} from '@jest/globals';
jest.useFakeTimers();
test('some test', () => {
expect(Date.now()).toBe(0);
});
此选项仅在使用默认的 jest-circus 测试运行器时支持。
maxConcurrency [number]
默认值:5
当使用 test.concurrent 时,此数值限制可同时运行的并发测试数量。超出此限制的测试将进入队列,待有可用资源时执行。
maxWorkers [number | string]
指定工作线程池为运行测试所创建的最大工作线程数。在单次运行模式下,默认值为机器可用核心数减一(为主线程预留)。在监视模式下,默认值为机器可用核心数的一半,以确保 Jest 保持非侵入性且不会导致机器卡顿。在资源有限的环境(如 CI)中调整此值可能有用,但默认值已满足大多数场景需求。
对于 CPU 资源不稳定的环境,可使用基于百分比的配置:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
maxWorkers: '50%',
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
maxWorkers: '50%',
};
export default config;
moduleDirectories [array<string>]
默认值:["node_modules"]
一个目录名称数组,将从被请求模块的位置开始向上递归搜索。设置此选项将覆盖默认值,若仍需搜索 node_modules 中的包,请将其包含在数组中:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
moduleDirectories: ['node_modules', 'bower_components'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
moduleDirectories: ['node_modules', 'bower_components'],
};
export default config;
不建议在 moduleDirectories 配置中使用 '.',因为这将导致作用域包(如 @emotion/react)无法访问同名子目录的包(如 react)。详情请参阅此 issue。大多数情况下,建议改用 moduleNameMapper 配置替代方案。
moduleFileExtensions [array<string>]
默认值:["js", "mjs", "cjs", "jsx", "ts", "mts", "cts", "tsx", "json", "node"]
模块使用的文件扩展名数组。当引入模块未指定扩展名时,Jest 将按从左到右顺序尝试这些扩展名。
建议将项目中最常用的扩展名置于数组左侧。例如使用 TypeScript 时,可考虑将 "ts" 和/或 "tsx" 移至数组开头。
moduleNameMapper [object<string, string | array<string>>]
默认值:null
提供从正则表达式到模块名称(或模块名称数组)的映射,用于通过单模块替换资源(如图片或样式)。
被映射的模块默认不会被模拟(mock),无论是否启用自动化模拟(automocking)。
如需引用文件路径,可使用 <rootDir> 字符串标记指向 rootDir 的值。
此外,可通过数字反向引用(numbered backreferences)替换捕获的正则表达式组。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
moduleNameMapper: {
'^image![a-zA-Z0-9$_-]+$': 'GlobalImageStub',
'^[./a-zA-Z0-9$_-]+\\.png$': '<rootDir>/RelativeImageStub.js',
'module_name_(.*)': '<rootDir>/substituted_module_$1.js',
'assets/(.*)': [
'<rootDir>/images/$1',
'<rootDir>/photos/$1',
'<rootDir>/recipes/$1',
],
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
moduleNameMapper: {
'^image![a-zA-Z0-9$_-]+$': 'GlobalImageStub',
'^[./a-zA-Z0-9$_-]+\\.png$': '<rootDir>/RelativeImageStub.js',
'module_name_(.*)': '<rootDir>/substituted_module_$1.js',
'assets/(.*)': [
'<rootDir>/images/$1',
'<rootDir>/photos/$1',
'<rootDir>/recipes/$1',
],
},
};
export default config;
映射定义顺序至关重要:规则将按序匹配直到命中。应将最具体的规则置于首位,模块名称数组的匹配顺序同理。
若提供的模块名未限定边界(^$),可能导致难以察觉的错误。例如 relay 会替换所有名称含 relay 子串的模块:relay、react-relay 和 graphql-relay 都将指向桩模块。
modulePathIgnorePatterns [array<string>]
默认值:[]
正则表达式字符串数组,用于在模块加载器可见性检测前匹配所有模块路径。若模块路径匹配任意模式,则在测试环境中不可通过 require() 引入。
这些模式字符串会匹配完整路径。请使用 <rootDir> 字符串标记包含项目根目录路径,防止不同环境(可能具有不同根目录)中意外忽略所有文件。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
modulePathIgnorePatterns: ['<rootDir>/build/'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
modulePathIgnorePatterns: ['<rootDir>/build/'],
};
export default config;
modulePaths [array<string>]
默认值:[]
此配置是设置 NODE_PATH 环境变量的替代 API,modulePaths 提供用于模块解析的绝对路径附加搜索目录。使用 <rootDir> 字符串标记包含项目根目录路径。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
modulePaths: ['<rootDir>/app/'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
modulePaths: ['<rootDir>/app/'],
};
export default config;
notify [boolean]
默认值:false
激活原生操作系统 测试结果通知功能。需额外安装 node-notifier 包:
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev node-notifier
yarn add --dev node-notifier
pnpm add --save-dev node-notifier
bun add --dev node-notifier
macOS 用户需在"系统设置 > 通知与专注模式"中允许 terminal-notifier 发送通知。
Windows 首次使用时,node-notifier 会创建开始菜单项且不显示通知,后续运行将正常显示。
notifyMode [string]
默认值:failure-change
指定通知模式。需要设置 notify: true。
模式
-
always:始终发送通知 -
failure:测试失败时发送通知 -
success:测试通过时发送通知 -
change:状态变更时发送通知 -
success-change:测试通过时发送通知,失败时发送一次通知 -
failure-change:测试失败时发送通知,通过时发送一次通知
openHandlesTimeout [数字]
默认值:1000
当 Jest 在完成测试后指定毫秒数内未能正常退出时,打印可能存在未关闭句柄的警告。设为 0 可禁用此警告。
preset [字符串]
默认: undefined
用作 Jest 配置基础的预设。预设应指向根目录包含 jest-preset.json、jest-preset.js、jest-preset.cjs 或 jest-preset.mjs 文件的 npm 模块。
例如,预设 foo-bar/jest-preset.js 将按以下方式配置:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
preset: 'foo-bar',
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
preset: 'foo-bar',
};
export default config;
预设也支持文件系统相对路径:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
preset: './node_modules/foo-bar/jest-preset.js',
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
preset: './node_modules/foo-bar/jest-preset.js',
};
export default config;
如果同时指定了 rootDir,该文件的解析路径将相对于该根目录。
prettierPath [字符串]
默认值:'prettier'
设置用于更新内联快照的 prettier 节点模块路径。
projects [数组<string | ProjectConfig>]
默认: undefined
当 projects 配置项被提供为路径或 glob 模式数组时,Jest 会同时运行所有指定项目的测试。适用于 monorepo 或多项目并行开发场景。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
projects: ['<rootDir>', '<rootDir>/examples/*'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
projects: ['<rootDir>', '<rootDir>/examples/*'],
};
export default config;
此配置示例将在根目录和 examples 目录下所有文件夹中运行 Jest。可在同一 Jest 实例中运行无限数量的项目。
此特性也可用于运行多个配置或多个运行器,需传递配置对象数组。例如在同次 Jest 调用中同时运行测试和 ESLint(通过 jest-runner-eslint):
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
projects: [
{
displayName: 'test',
},
{
displayName: 'lint',
runner: 'jest-runner-eslint',
testMatch: ['<rootDir>/**/*.js'],
},
],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
projects: [
{
displayName: 'test',
},
{
displayName: 'lint',
runner: 'jest-runner-eslint',
testMatch: ['<rootDir>/**/*.js'],
},
],
};
export default config;
使用多项目运行器时,建议为每个项目添加 displayName,该项目的 displayName 将显示在对应测试旁边。
启用 projects 选项后,Jest 会将根级配置选项复制到每个子配置中,并在子上下文中解析值。这意味着即使 <rootDir> 等字符串标记定义在根配置中,也会指向_子项目的根目录_。
randomize [布尔值]
默认值:false
等同于 --randomize 标志,用于随机化文件中测试的执行顺序。
reporters [数组<moduleName | [moduleName, options]>]
默认: undefined
使用此配置选项为 Jest 添加报告器。必须是报告器名称列表,可通过元组形式传递额外选项:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
reporters: [
'default',
['<rootDir>/custom-reporter.js', {banana: 'yes', pineapple: 'no'}],
],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
reporters: [
'default',
['<rootDir>/custom-reporter.js', {banana: 'yes', pineapple: 'no'}],
],
};
export default config;
默认报告器
如果指定了自定义报告器,将会覆盖 Jest 的默认报告器。若需保留默认报告器,必须将 'default' 作为报告器名称传入:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
reporters: [
'default',
['jest-junit', {outputDirectory: 'reports', outputName: 'report.xml'}],
],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
reporters: [
'default',
['jest-junit', {outputDirectory: 'reports', outputName: 'report.xml'}],
],
};
export default config;
GitHub Actions 报告器
若将其加入报告器列表,内置的 GitHub Actions 报告器会通过注释方式在变更文件中显示测试失败信息,并(配合 'silent: false' 使用时)利用 GitHub 分组功能打印便于导航的日志。注意此时不应使用 'default',因为 'github-actions' 已包含其功能,请确保同时包含 'summary'。若仅需注释功能,只需单独添加该报告器(其默认值 'silent' 为 'true'):
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
reporters: [['github-actions', {silent: false}], 'summary'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
reporters: [['github-actions', {silent: false}], 'summary'],
};
export default config;
摘要报告器
摘要报告器打印所有测试的概要信息。它是默认报告器的组成部分,因此当报告器列 表包含 'default' 时会自动启用。例如,您可能需要将其作为独立报告器替代默认报告器,或与 静默报告器 搭配使用:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
reporters: ['jest-silent-reporter', 'summary'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
reporters: ['jest-silent-reporter', 'summary'],
};
export default config;
summary 报告器接受配置选项。由于它包含在 default 报告器中,您也可以通过默认报告器传递这些选项。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
reporters: [['default', {summaryThreshold: 10}]],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
reporters: [['default', {summaryThreshold: 10}]],
};
export default config;
summaryThreshold 选项的行为如下:当测试套件总数超过此阈值时,将在执行完所有测试后打印详细的失败测试摘要。该选项默认值为 20。
自定义报告器
需要更多报告器?查看 Awesome Jest 提供的 丰富报告器列表。
自定义报告器模块必须导出一个类,其构造函数接收 globalConfig、reporterOptions 和 reporterContext 作为参数:
class CustomReporter {
constructor(globalConfig, reporterOptions, reporterContext) {
this._globalConfig = globalConfig;
this._options = reporterOptions;
this._context = reporterContext;
}
onRunComplete(testContexts, results) {
console.log('Custom reporter output:');
console.log('global config:', this._globalConfig);
console.log('options for this reporter from Jest config:', this._options);
console.log('reporter context passed from test scheduler:', this._context);
}
// Optionally, reporters can force Jest to exit with non zero code by returning
// an `Error` from `getLastError()` method.
getLastError() {
if (this._shouldFail) {
return new Error('Custom error reported!');
}
}
}
module.exports = CustomReporter;
完整钩子列表和参数类型请参阅 packages/jest-reporters/src/types.ts 中的 Reporter 接口。
resetMocks [布尔值]
默认值:false
在每个测试前自动重置模拟状态。相当于在每个测试前调用 jest.resetAllMocks()。这将清除所有模拟的伪造实现,但不会恢复其初始实现。
resetModules [布尔值]
默认值:false
默认情况下,每个测试文件拥有独立的模块注册表。启用 resetModules 会在运行每个测试前额外重置模块注册表。这对于隔离每个测试的模块非常有用,可避免局部模块状态在测试间产生冲突。您也可以通过 jest.resetModules() 以编程方式实现此功能。
resolver [字符串]
默认: undefined
此选项允许使用自定义解析器。该解析器必须是导出以下内容之一的模块:
-
接收两个参数的函数:第一个参数为待解析路径(字符串),第二个参数为配置对象。函数应返回解析后的模块路径,或在找不到模块时抛出错误;或
-
包含
async和/或sync属性的对象。sync属性应为符合上述要求的函数,async属性也应为接收相同参数的函数,但需返回解析为模块路径的 Promise 或拒绝状态的错误。
提供给解析器的配置对象结构如下:
type ResolverOptions = {
/** Directory to begin resolving from. */
basedir: string;
/** List of export conditions. */
conditions?: Array<string>;
/** Instance of default resolver. */
defaultResolver: (path: string, options: ResolverOptions) => string;
/** Instance of default async resolver. */
defaultAsyncResolver: (
path: string,
options: ResolverOptions,
) => Promise<string>;
/** List of file extensions to search in order. */
extensions?: Array<string>;
/** List of directory names to be looked up for modules recursively. */
moduleDirectory?: Array<string>;
/** List of `require.paths` to use if nothing is found in `node_modules`. */
paths?: Array<string>;
/** Current root directory. */
rootDir?: string;
};
作为选项传入的 defaultResolver 是 Jest 的默认解析器,在编写自定义解析器时可能非常有用。它接受与自定义同步解析器相同的参数(例如 (path, options)),并返 回字符串或抛出异常。
类似地,defaultAsyncResolver 是默认的异步解析器,它接受相同参数并返回一个解析为字符串或拒绝错误的 Promise。
例如,若需遵循 Browserify 的 "browser" 字段,可使用以下解析器:
const browserResolve = require('browser-resolve');
module.exports = browserResolve.sync;
并将其添加到 Jest 配置中:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
resolver: '<rootDir>/resolver.js',
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
resolver: '<rootDir>/resolver.js',
};
export default config;
Jest 的 jest-resolve 依赖于 unrs-resolver。我们可以传递额外选项,例如修改解析时的 mainFields。对于 React Native 项目,可能需要如下配置:
module.exports = (path, options) => {
// Call the defaultResolver, so we leverage its cache, error handling, etc.
return options.defaultResolver(path, {
...options,
// `unrs-resolver` option: https://github.com/unrs/unrs-resolver#main-field
mainFields: ['react-native', 'main'],
});
};
也可利用 defaultResolver 实现"预处理器",用于改变默认解析器的模块解析行为。例如在 TypeScript 项目中,若需在运行时引用 .js 文件但使用 .ts 文件运行测试:
module.exports = (path, options) => {
// Dynamic imports within our codebase that reference .js need to reference
// .ts during tests.
if (
!options.basedir.includes('node_modules') &&
path.endsWith('.js') &&
(path.startsWith('../') || path.startsWith('./'))
) {
path = path.replace(/\.js$/, '.ts');
}
// Call the defaultResolver, so we leverage its cache, error handling, etc.
return options.defaultResolver(path, options);
};
restoreMocks [布尔值]
默认值:false
在每个测试前自动恢复模拟状态和实现。相当于在每个测试前调用 jest.restoreAllMocks()。这将移除所有模拟函数的虚假实现并恢复其原始实现。
rootDir [字符串]
默认值:包含 Jest 配置文件 的目录根路径,或 package.json 所在目录,若未找到 package.json 则使用 pwd 当前工作目录
Jest 扫描测试文件和模块的根目录。若将 Jest 配置置于 package.json 中且希望根目录是代码库的根路径,此配置项默认值为 package.json 所在目录。
通常可设置为 'src' 或 'lib',对应代码库中实际存储源码的目录。
在其他路径配置中使用 '<rootDir>' 字符串占位符时,将自动引用此值。例如若要使 setupFiles 指向项目根目录的 some-setup.js 文件,应设置为:'<rootDir>/some-setup.js'。
roots [数组<字符串>]
默认值:["<rootDir>"]
定义 Jest 搜索文件的目录路径列表。
适用于仅需在特定子目录(如代码库中的 src/ 目录)搜索测试,同时避免扫描其他区域的情况。
rootDir 主要作为占位符用于其他配置项,而 roots 被 Jest 内部用于定位测试文件与源码文件。此规则同样适用于 从 node_modules 加载手动模拟模块的场景(此时 __mocks__ 必须位于某个 roots 路径下)。
默认 roots 为单条目 <rootDir>,但在某些场景下可能需要配置多根目录,例如:roots: ["<rootDir>/src/", "<rootDir>/tests/"]。
runtime [字符串]
默认值:"jest-runtime"
此选项允许使用自定义运行时来执行测试文件。可通过指定运行时实现的路径来提供自定义运行时。
运行时模块必须导出一个类,该类需继承自 Jest 默认的 Runtime 类,或实现具有相同构造函数签名和方法的兼容接口。
示例:
const {default: Runtime} = require('jest-runtime');
class CustomRuntime extends Runtime {
//...custom logic
}
module.exports = CustomRuntime;
import Runtime from 'jest-runtime';
export default class CustomRuntime extends Runtime {
//...custom logic
}
将自定义运行时添加到 Jest 配置中:
- JavaScript
- TypeScript
module.exports = {
runtime: './custom-runtime.js',
};
export default {
runtime: './custom-runtime.ts',
};
runner [字符串]
默认值:"jest-runner"
此选项允许使用自定义运行器替代 Jest 默认测试运行器。常见运行器包括:
runner 属性值可以省略包名的 jest-runner- 前缀。
要编写测试运行器,需导出一个类:其构造函数接收 globalConfig,并包含以下签名的 runTests 方法:
async function runTests(
tests: Array<Test>,
watcher: TestWatcher,
onStart: OnTestStart,
onResult: OnTestSuccess,
onFailure: OnTestFailure,
options: TestRunnerOptions,
): Promise<void>;
如果需限制测试运行器仅串行执行而非并行运行,类中应设置 isSerial 属性为 true。
sandboxInjectedGlobals [array<string>]
Jest 28 中由 extraGlobals 重命名而来。
默认: undefined
测试文件在 vm 中运行,这会减慢对全局上下文属性(如 Math)的调用。通过此选项可指定需在 vm 内额外定义的属性以加速查找。
例如,若测试频繁调用 Math,可通过设置 sandboxInjectedGlobals 将其传入:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
sandboxInjectedGlobals: ['Math'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
sandboxInjectedGlobals: ['Math'],
};
export default config;
若使用原生 ESM,此选项无效。
setupFiles [array]
默认值:[]
用于配置或初始化测试环境的模块路径列表。每个 setupFile 在每个测试文件中仅执行一次。由于每个测试在独立环境中运行,这些脚本会在执行 setupFilesAfterEnv 前及测试代码本身前于测试环境中运行。
若安装脚本是 CJS 模块,可导出异步函数。Jest 将调用该函数并等待其结果,适用于异步获取数据。若为 ESM 模块,直接使用顶层 await 即可实现相同效果。
setupFilesAfterEnv [array]
默认值:[]
用于在测试套件中每个测试文件执行前配置或初始化测试框架的模块路径列表。由于 setupFiles 在测试框架安装到环境前执行,此脚本提供在测试框架安装后但测试代码执行前运行代码的机会。
换言之,setupFilesAfterEnv 模块适用于每个测试文件中重复的代码。测试框架安装后,Jest 全局对象、jest 对象 和 expect 将在模块中可访问。例如,可添加 jest-extended 库的额外匹配器,或调用设置与清理钩子:
const matchers = require('jest-extended');
expect.extend(matchers);
afterEach(() => {
jest.useRealTimers();
});
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
setupFilesAfterEnv: ['<rootDir>/setup-jest.js'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
setupFilesAfterEnv: ['<rootDir>/setup-jest.js'],
};
export default config;
若安装脚本是 CJS 模块,可导出异步函数。Jest 将调用该函数并等待其结果,适用于异步获取数据。若为 ESM 模块,直接使用顶层 await 即可实现相同效果。
showSeed [boolean]
默认值:false
等效于 --showSeed 标志,用于在测试报告摘要中显示随机种子。
slowTestThreshold [number]
默认值:5
测试执行超过该秒数将被标记为运行缓慢,并在结果中特别标注。
snapshotFormat [对象]
默认值:{escapeString: false, printBasicPrototype: false}
允许覆盖pretty-format文档中特定的快照格式化选项(compareKeys和plugins除外)。例如以下配置会让快照格式化器省略"Object"和"Array"的前缀:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
snapshotFormat: {
printBasicPrototype: false,
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
snapshotFormat: {
printBasicPrototype: false,
},
};
export default config;
test('does not show prototypes for object and array inline', () => {
const object = {
array: [{hello: 'Danger'}],
};
expect(object).toMatchInlineSnapshot(`
{
"array": [
{
"hello": "Danger",
},
],
}
`);
});
snapshotResolver [字符串]
默认: undefined
用于解析测试用例与快照文件路径的模块路径。通过此配置可自定义Jest存储快照文件的磁盘位置。
module.exports = {
// resolves from test to snapshot path
resolveSnapshotPath: (testPath, snapshotExtension) =>
testPath.replace('__tests__', '__snapshots__') + snapshotExtension,
// resolves from snapshot to test path
resolveTestPath: (snapshotFilePath, snapshotExtension) =>
snapshotFilePath
.replace('__snapshots__', '__tests__')
.slice(0, -snapshotExtension.length),
// Example test path, used for preflight consistency check of the implementation above
testPathForConsistencyCheck: 'some/__tests__/example.test.js',
};
snapshotSerializers [字符串数组]
默认值:[]
Jest在快照测试中使用的序列化模块路径列表。
Jest内置了对JavaScript原生类型、HTML元素(Jest 20.0.0+)、ImmutableJS(Jest 20.0.0+)和React元素的序列化支持。详见快照测试教程。
- JavaScript
- TypeScript
module.exports = {
serialize(val, config, indentation, depth, refs, printer) {
return `Pretty foo: ${printer(val.foo, config, indentation, depth, refs)}`;
},
test(val) {
return val && Object.prototype.hasOwnProperty.call(val, 'foo');
},
};
import type {Plugin} from 'pretty-format';
const plugin: Plugin = {
serialize(val, config, indentation, depth, refs, printer): string {
return `Pretty foo: ${printer(val.foo, config, indentation, depth, refs)}`;
},
test(val): boolean {
return val && Object.prototype.hasOwnProperty.call(val, 'foo');
},
};
export default plugin;
printer是使用现有插件序列化值的函数。
在Jest配置中添加custom-serializer:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
snapshotSerializers: ['path/to/custom-serializer.js'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
snapshotSerializers: ['path/to/custom-serializer.ts'],
};
export default config;
测试用例将呈现如下形式:
test(() => {
const bar = {
foo: {
x: 1,
y: 2,
},
};
expect(bar).toMatchSnapshot();
});
生成的快照:
Pretty foo: Object {
"x": 1,
"y": 2,
}
要让依赖关系显式化而非隐式化,可在单个测试文件中调用expect.addSnapshotSerializer添加序列化模块,而非在Jest配置的snapshotSerializers中添加路径。
序列化器API详见此处。
testEnvironment [字符串]
默认值:"node"
用于测试的执行环境。Jest默认使用Node.js环境。构建Web应用时,可通过jsdom使用类浏览器环境。
在文件顶部添加@jest-environment文档块可为该文件所有测试指定执行环境:
/**
* @jest-environment jsdom
*/
test('use jsdom in this test file', () => {
const element = document.createElement('div');
expect(element).not.toBeNull();
});
可创建自定义环境配置模块,该模块需导出包含setup、teardown和getVmContext方法的类。通过向this.global对象赋值,可将变量注入测试套件的全局作用域。构造函数接收globalConfig和projectConfig作为第一参数,testEnvironmentContext作为第二参数。
该类可选择性地暴露一个异步方法 handleTestEvent,用于绑定由 jest-circus 触发的事件。通常,jest-circus 测试运行器会暂停执行,直到 handleTestEvent 返回的 Promise 被完成,但以下事件除外:start_describe_definition、finish_describe_definition、add_hook、add_test 或 error(完整列表可参考类型定义中的 SyncEvent 类型)。这是出于向后兼容性和 process.on('unhandledRejection', callback) 签名的考虑,但对大多数使用场景通常不会造成问题。
测试文件中的任何文档块编译指示(docblock pragmas)将被传递给环境构造函数,可用于按测试进行配置。如果编译指示没有值,它将以空字符串形式出现在对象中;如果编译指示不存在,则不会出现在对象中。
要将此类用作自定义环境,请通过项目中的完整路径引用它。例如,如果您的类位于项目子文件夹的 my-custom-environment.js 文件中,则注解应如下所示:
/**
* @jest-environment ./src/test/my-custom-environment
*/
TestEnvironment 是沙盒化的。每个测试套件将在其专属的 TestEnvironment 中触发设置/拆卸操作。
示例:
// my-custom-environment
const NodeEnvironment = require('jest-environment-node').TestEnvironment;
class CustomEnvironment extends NodeEnvironment {
constructor(config, context) {
super(config, context);
console.log(config.globalConfig);
console.log(config.projectConfig);
this.testPath = context.testPath;
this.docblockPragmas = context.docblockPragmas;
}
async setup() {
await super.setup();
await someSetupTasks(this.testPath);
this.global.someGlobalObject = createGlobalObject();
// Will trigger if docblock contains @my-custom-pragma my-pragma-value
if (this.docblockPragmas['my-custom-pragma'] === 'my-pragma-value') {
// ...
}
}
async teardown() {
this.global.someGlobalObject = destroyGlobalObject();
await someTeardownTasks();
await super.teardown();
}
getVmContext() {
return super.getVmContext();
}
async handleTestEvent(event, state) {
if (event.name === 'test_start') {
// ...
}
}
}
module.exports = CustomEnvironment;
// my-test-suite
/**
* @jest-environment ./my-custom-environment
*/
let someGlobalObject;
beforeAll(() => {
someGlobalObject = globalThis.someGlobalObject;
});
testEnvironmentOptions [对象]
默认值:{}
传递给 testEnvironment 的测试环境选项。具体选项取决于所选环境。
例如,您可以覆盖传递给 jsdom 的选项:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
testEnvironment: 'jsdom',
testEnvironmentOptions: {
html: '<html lang="zh-cmn-Hant"></html>',
url: 'https://jestjs.io/',
userAgent: 'Agent/007',
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
testEnvironment: 'jsdom',
testEnvironmentOptions: {
html: '<html lang="zh-cmn-Hant"></html>',
url: 'https://jestjs.io/',
userAgent: 'Agent/007',
},
};
export default config;
jest-environment-jsdom 和 jest-environment-node 都支持指定 customExportConditions,用于控制从 package.json 的 exports 字段加载库的哪个版本。jest-environment-jsdom 默认值为 ['browser'],jest-environment-node 默认值为 ['node', 'node-addons']。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
testEnvironment: 'jsdom',
testEnvironmentOptions: {
customExportConditions: ['react-native'],
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
testEnvironment: 'jsdom',
testEnvironmentOptions: {
customExportConditions: ['react-native'],
},
};
export default config;
这些选项也可以通过文档块传递,方式类似 testEnvironment。选项字符串必须能被 JSON.parse 解析:
/**
* @jest-environment jsdom
* @jest-environment-options {"url": "https://jestjs.io/"}
*/
test('use jsdom and set the URL in this test file', () => {
expect(window.location.href).toBe('https://jestjs.io/');
});
testFailureExitCode [数字]
默认值:1
测试失败时 Jest 返回的退出码。
此设置不会改变 Jest 自身错误(例如无效配置)时的退出码 。
testMatch [字符串 | 数组<字符串>]
(默认值:[ "**/__tests__/**/*.?([mc])[jt]s?(x)", "**/?(*.)+(spec|test).?([mc])[jt]s?(x)" ])
Jest 用于检测测试文件的 glob 模式。默认会查找 __tests__ 文件夹内所有 .js、.jsx、.ts 和 .tsx 文件,以及任何后缀为 .test 或 .spec 的文件(如 Component.test.js 或 Component.spec.js),同时也会识别名为 test.js 或 spec.js 的文件。
具体模式规范请参阅 micromatch 包文档。
另请参见 testRegex [字符串 | 数组<字符串>],注意不能同时配置这两个选项。
每个 glob 模式按配置中的 顺序依次应用。例如 ["!**/__fixtures__/**", "**/__tests__/**/*.js"] 不会排除 __fixtures__ 目录,因为第二个模式覆盖了排除规则。要使排除生效,需将否定模式置于 **/__tests__/**/*.js 之后。
testPathIgnorePatterns [array<string>]
默认值:["/node_modules/"]
这是一个正则表达式字符串数组,在执行测试前会匹配所有测试路径。如果测试路径匹配其中任意模式,该测试将被跳过。
这些模式字符串会匹配完整路径。使用 <rootDir> 字符串标记可包含项目根目录路径,防止在不同环境下因根目录不同而意外忽略所有文件。例如:["<rootDir>/build/", "<rootDir>/node_modules/"]。
testRegex [string | array<string>]
默认值:(/__tests__/.*|(\\.|/)(test|spec))\\.[mc]?[jt]sx?$
Jest 用于检测测试文件的匹配模式。默认情况下,它会查找 __tests__ 文件夹内的 .js、.jsx、.ts 和 .tsx 文件,以及任何后缀为 .test 或 .spec 的文件(例如 Component.test.js 或 Component.spec.js)。同时也会识别名为 test.js 或 spec.js 的文件 。另请参阅 testMatch [字符串 | 数组<字符串>],但请注意这两个选项不能同时指定。
以下是默认正则表达式的可视化说明:
├── __tests__
│ └── component.spec.js # test
│ └── anything # test
├── package.json # not test
├── foo.test.js # test
├── bar.spec.jsx # test
└── component.js # not test
testRegex 会尝试使用绝对文件路径检测测试文件,因此若存在名称匹配的文件夹,其中所有文件都将作为测试运行。
testResultsProcessor [string]
默认: undefined
此选项允许使用自定义结果处理器。该处理器必须是一个 Node 模块,导出一个函数:该函数接收特定结构的对象作为第一个参数,并返回处理后的对象。
{
"success": boolean,
"startTime": epoch,
"numTotalTestSuites": number,
"numPassedTestSuites": number,
"numFailedTestSuites": number,
"numRuntimeErrorTestSuites": number,
"numTotalTests": number,
"numPassedTests": number,
"numFailedTests": number,
"numPendingTests": number,
"numTodoTests": number,
"openHandles": Array<Error>,
"testResults": [{
"numFailingTests": number,
"numPassingTests": number,
"numPendingTests": number,
"testResults": [{
"title": string (message in it block),
"status": "failed" | "pending" | "passed",
"ancestorTitles": [string (message in describe blocks)],
"failureMessages": [string],
"numPassingAsserts": number,
"location": {
"column": number,
"line": number
},
"duration": number | null,
"startAt": epoch | null
},
...
],
"perfStats": {
"end": epoch,
"loadTestEnvironmentEnd": epoch,
"loadTestEnvironmentStart": epoch,
"runtime": number,
"setupAfterEnvEnd": epoch,
"setupAfterEnvStart": epoch,
"setupFilesEnd": epoch,
"setupFilesStart": epoch,
"slow": boolean,
"start": epoch
},
"testFilePath": absolute path to test file,
"coverage": {}
},
"testExecError:" (exists if there was a top-level failure) {
"message": string
"stack": string
}
...
]
}
testResultsProcessor 和 reporters 功能非常相似。主要区别在于测试结果处理器仅在所有测试完成后被调用,而报告器可以在单个测试和/或测试套件完成后接收测试结果。
testRunner [string]
默认值:jest-circus/runner
此选项允许使用自定义测试运行器。默认运行器是 jest-circus。可通过指定测试运行器实现路径来提供自定义运行器。
测试运行器模块必须导出一个具有以下签名的函数:
function testRunner(
globalConfig: GlobalConfig,
config: ProjectConfig,
environment: Environment,
runtime: Runtime,
testPath: string,
): Promise<TestResult>;
示例函数可参考我们默认的 jasmine2 测试运行器包。
testSequencer [string]
默认值:@jest/test-sequencer
此选项允许使用自定义排序器替代 Jest 的默认排序器。
sort 和 shard 函数均可选择返回一个 Promise。
例如,您可以按字母顺序排序测试路径:
const Sequencer = require('@jest/test-sequencer').default;
class CustomSequencer extends Sequencer {
/**
* Select tests for shard requested via --shard=shardIndex/shardCount
* Sharding is applied before sorting
*/
shard(tests, {shardIndex, shardCount}) {
const shardSize = Math.ceil(tests.length / shardCount);
const shardStart = shardSize * (shardIndex - 1);
const shardEnd = shardSize * shardIndex;
return [...tests]
.sort((a, b) => (a.path > b.path ? 1 : -1))
.slice(shardStart, shardEnd);
}
/**
* Sort test to determine order of execution
* Sorting is applied after sharding
*/
sort(tests) {
// Test structure information
// https://github.com/jestjs/jest/blob/6b8b1404a1d9254e7d5d90a8934087a9c9899dab/packages/jest-runner/src/types.ts#L17-L21
const copyTests = [...tests];
return copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1));
}
}
module.exports = CustomSequencer;
在 Jest 配置中添加 custom-sequencer:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
testSequencer: 'path/to/custom-sequencer.js',
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
testSequencer: 'path/to/custom-sequencer.js',
};
export default config;
testTimeout [number]
默认值:5000
测试的默认超时时间(毫秒)。
transform [object<string, pathToTransformer | [pathToTransformer, object]>]
默认值:{"\\.[jt]sx?$": "babel-jest"}
一个从正则表达式到转换器路径的 映射。可选地,可以传递包含配置选项的元组作为第二个参数:{filePattern: ['path-to-transformer', {options}]}。例如,以下是如何配置 babel-jest 实现非默认行为:{'\\.js$': ['babel-jest', {rootMode: 'upward'}]}。
Jest 以 JavaScript 形式运行项目代码,因此当使用 Node 环境默认不支持的语法时(如 JSX、TypeScript、Vue 模板),就需要转换器。默认情况下,Jest 会使用 babel-jest 转换器,它会加载项目的 Babel 配置并转换所有匹配 /\.[jt]sx?$/ 正则表达式的文件(即任何 .js、.jsx、.ts 或 .tsx 文件)。此外,babel-jest 会注入 ES 模块模拟 中提到的模拟提升功能所需的 Babel 插件。
更多细节及构建自定义转换器的说明,请参阅 代码转换 章节。
请记住,转换器在每个文件上仅运行一次(除非文件发生变 更)。
如果需要在其他代码预处理器中使用默认的 babel-jest 转换器,请务必显式包含它:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
transform: {
'\\.[jt]sx?$': 'babel-jest',
'\\.css$': 'some-css-transformer',
},
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
transform: {
'\\.[jt]sx?$': 'babel-jest',
'\\.css$': 'some-css-transformer',
},
};
export default config;
transformIgnorePatterns [array<string>]
默认值:["/node_modules/", "\\.pnp\\.[^\\\/]+$"]
一个正则表达式模式字符串数组,用于在转换前匹配所有源文件路径。如果文件路径匹配任意模式,则该文件不会被转换。
注意:提供重叠的正则表达式模式可能导致预期转换的文件未被转换。例如:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
transformIgnorePatterns: ['/node_modules/(?!(foo|bar)/)', '/bar/'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
transformIgnorePatterns: ['/node_modules/(?!(foo|bar)/)', '/bar/'],
};
export default config;
第一个模式会匹配(因此不转换)/node_modules 目录内的文件(除了 /node_modules/foo/ 和 /node_modules/bar/ 中的文件)。第二个模式会匹配(因此不转换)任何包含 /bar/ 路径的文件。两者结合时,/node_modules/bar/ 中的文件虽被第一个模式排除,但因匹配第二个模式而不会被转换。
某些情况下(尤其在 React Native 或 TypeScript 项目中),第三方模块会发布未转译的代码。由于默认不转换 node_modules 内的文件,Jest 无法理解这些模块的代码,导致语法错误。此时可使用 transformIgnorePatterns 允许转换特定模块。React Native 指南 提供了此用例的典型示例。
这些模式字符串会匹配完整路径。请使用 <rootDir> 字符串标记包含项目根目录路径,防止不同环境(可能具有不同根目录)中意外忽略所有文件。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
transformIgnorePatterns: [
'<rootDir>/bower_components/',
'<rootDir>/node_modules/',
],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
transformIgnorePatterns: [
'<rootDir>/bower_components/',
'<rootDir>/node_modules/',
],
};
export default config;
如果你使用 pnpm 且需要转换 node_modules 下的某些包,请注意该目录下的包(例如 node_modules/package-a/)已被符号链接到 .pnpm 下的路径(例如 node_modules/.pnpm/package-a@x.x.x/node_modules/package-a/)。因此直接使用 <rootDir>/node_modules/(?!(package-a|@scope/pkg-b)/) 无法匹配,而应使用:
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
transformIgnorePatterns: [
'<rootDir>/node_modules/.pnpm/(?!(package-a|@scope\\+pkg-b)@)',
/* if config file is under '~/packages/lib-a/' */
`${path.join(
__dirname,
'../..',
)}/node_modules/.pnpm/(?!(package-a|@scope\\+pkg-b)@)`,
/* or using relative pattern to match the second 'node_modules/' in 'node_modules/.pnpm/@scope+pkg-b@x.x.x/node_modules/@scope/pkg-b/' */
'node_modules/(?!.pnpm|package-a|@scope/pkg-b)',
],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
transformIgnorePatterns: [
'<rootDir>/node_modules/.pnpm/(?!(package-a|@scope\\+pkg-b)@)',
/* if config file is under '~/packages/lib-a/' */
`${path.join(
__dirname,
'../..',
)}/node_modules/.pnpm/(?!(package-a|@scope\\+pkg-b)@)`,
/* or using relative path to match the second 'node_modules/' in 'node_modules/.pnpm/@scope+pkg-b@x.x.x/node_modules/@scope/pkg-b/' */
'node_modules/(?!.pnpm|package-a|@scope/pkg-b)',
],
};
export default config;
需注意:.pnpm 下的文件夹命名格式为 "包名@版本号",因此使用 / 无法识别路径,而应使用 @ 符号。
unmockedModulePathPatterns [array<string>]
默认值:[]
正则表达式模式字符串数组,用于在模块加载器自动返回模拟模块前匹配所有模块。若模块路径匹配此列表中的任何模式,则不会被自动模拟。
此配置适用于常被用作底层实现的工具类模块(如 underscore、lodash 等)。最佳实践是尽量精简此列表,并在单个测试中使用显式的 jest.mock()/jest.unmock() 调用。显式的测试级设置能让其他测试阅读者更清晰地理解测试运行环境。
可在测试文件中通过显式调用 jest.mock() 覆盖此配置。
verbose [boolean]
默认值: false(当仅运行单个测试文件时为 true)
指示是否在运行期间报告每个独立测试的执行情况。所有错误仍会在执行结束后显示在底部。
waitForUnhandledRejections [boolean]
为 rejectionHandled、uncaughtException 或 unhandledRejection 事件预留一个事件循环周期。
未启用此选项时,Jest 可能误报错误(例如将已处理的拒绝报告为未处理),或漏报实际的未处理拒绝(或将其错误归因于其他测试用例)。
此选项可能对 快速测试套件产生显著性能开销。
watchPathIgnorePatterns [array<string>]
默认值:[]
在监视模式下重新运行测试前,此正则表达式数组将与所有源文件路径进行匹配。若文件路径匹配任意模式,则该文件更新时不会触发测试重新运行。
这些模式将匹配完整路径。使用 <rootDir> 路径令牌可包含项目根目录路径,避免因环境差异导致根目录不同而意外忽略文件。示例:["<rootDir>/node_modules/"]。
即使此处未指定任何模式,监视器仍会忽略版本控制文件夹(.git、.hg、.sl)的变更。默认情况下会监视其他隐藏文件和目录(即以点号.开头的文件)。将其加入 watchPathIgnorePatterns 时请转义点号,因为它在正则表达式中是特殊字符。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
watchPathIgnorePatterns: ['<rootDir>/\\.tmp/', '<rootDir>/bar/'],
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
watchPathIgnorePatterns: ['<rootDir>/\\.tmp/', '<rootDir>/bar/'],
};
export default config;
watchPlugins [数组<string | [string, Object]>]
默认值:[]
此选项允许使用自定义监视插件。详见监视插件文档。
监视插件示例包括:
在 watchPlugins 属性值中可省略包名的 jest-watch- 前缀。
watchman [布尔值]
默认值:true
是否使用 watchman 进行文件监控。
workerIdleMemoryLimit [数值 | 字符串]
默认: undefined
指定工作线程回收前的内存限制,主要用于解决此问题;
工作线程执行测试后会检测其内存占用。若超过指定值,该线程会被终止并重启。可通过多种方式指定限制值,最终结果将使用 Math.floor 转换为整数值:
-
<= 1- 视为系统内存百分比(如 0.5 表示限制为系统总内存的 50%) -
\> 1- 视为固定字节值(由于前条规则,若需设置 1 字节限制需使用1.1) -
带单位表示
50%- 系统内存百分比100KB/65MB等 - 固定内存限制K/KB- 千字节 (x1000)KiB- 二进制千字节 (x1024)M/MB- 兆字节MiB- 二进制兆字节G/GB- 千兆字节GiB- 二进制千兆字节
基于百分比的内存限制在 Linux CircleCI 工作节点上无效,因系统内存报告不准确。
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
workerIdleMemoryLimit: 0.2,
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
workerIdleMemoryLimit: 0.2,
};
export default config;
// [字符串]
此选项允许在 package.json 中添加注释。将注释文本作为该键的值:
{
"name": "my-project",
"jest": {
"//": "Comment goes here",
"verbose": true
}
}
workerThreads
默认值:false
是否使用 worker threads 进行并行化处理。默认情况下使用 子进程。
使用工作线程可提升性能
此为实验性功能。注意工作线程使用结构化克隆(structured clone)而非 JSON.stringify() 序列化消息,意味着内置对象如 BigInt/Map/Set 可正确序列化,但 Error/Map/Set 上的额外属性不会被传递。详见结构化克隆算法。