配置 Jest
Jest 的理念是默认情况下运行良好,但有时您只需要更多配置能力。
建议在专用的 JavaScript、TypeScript 或 JSON 文件中定义配置。如果文件名为 jest.config.js|ts|mjs|cjs|json
,则会自动发现该文件。您可以使用 --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,
};
};
要读取 TypeScript 配置文件,Jest 需要 ts-node
。确保它已安装在您的项目中。
配置也可以存储在 JSON 文件中,作为普通对象
{
"bail": 1,
"verbose": true
}
或者,Jest 的配置可以通过项目 package.json
中的 "jest"
键定义
{
"name": "my-project",
"jest": {
"verbose": true
}
}
选项
您可以从 jest-config
中检索 Jest 的默认值,并在需要时扩展它们
- JavaScript
- TypeScript
const {defaults} = require('jest-config');
/** @type {import('jest').Config} */
const config = {
moduleFileExtensions: [...defaults.moduleFileExtensions, 'mts', 'cts'],
};
module.exports = config;
import type {Config} from 'jest';
import {defaults} from 'jest-config';
const config: Config = {
moduleFileExtensions: [...defaults.moduleFileExtensions, 'mts'],
};
export default config;
automock
[布尔值]bail
[数字 | 布尔值]cacheDirectory
[字符串]clearMocks
[布尔值]collectCoverage
[布尔值]collectCoverageFrom
[数组]coverageDirectory
[字符串]coveragePathIgnorePatterns
[数组<字符串>]coverageProvider
[字符串]coverageReporters
[数组<字符串 | [字符串,选项]>]coverageThreshold
[对象]dependencyExtractor
[字符串]displayName
[字符串,对象]errorOnDeprecated
[布尔值]extensionsToTreatAsEsm
[数组<字符串>]fakeTimers
[对象]forceCoverageMatch
[数组<字符串>]globals
[对象]globalSetup
[字符串]globalTeardown
[字符串]haste
[对象]injectGlobals
[布尔值]maxConcurrency
[数字]maxWorkers
[数字 | 字符串]moduleDirectories
[数组<字符串>]moduleFileExtensions
[数组<字符串>]moduleNameMapper
[对象<字符串,字符串 | 数组<字符串>>]modulePathIgnorePatterns
[数组<字符串>]modulePaths
[数组<字符串>]notify
[布尔值]notifyMode
[字符串]openHandlesTimeout
[数字]preset
[字符串]prettierPath
[字符串]projects
[数组<字符串 | ProjectConfig>]randomize
[布尔值]reporters
[数组<模块名 | [模块名,选项]>]resetMocks
[布尔值]resetModules
[布尔值]resolver
[字符串]restoreMocks
[布尔值]rootDir
[字符串]roots
[数组<字符串>]runner
[字符串]sandboxInjectedGlobals
[数组<字符串>]setupFiles
[数组]setupFilesAfterEnv
[数组]showSeed
[布尔值]slowTestThreshold
[数字]snapshotFormat
[对象]snapshotResolver
[字符串]snapshotSerializers
[数组<字符串>]testEnvironment
[字符串]testEnvironmentOptions
[对象]testFailureExitCode
[数字]testMatch
[数组<字符串>]testPathIgnorePatterns
[数组<字符串>]testRegex
[字符串 | 数组<字符串>]testResultsProcessor
[字符串]testRunner
[字符串]testSequencer
[字符串]testTimeout
[数字]transform
[对象<字符串,路径到转换器 | [路径到转换器,对象]>]transformIgnorePatterns
[数组<字符串>]unmockedModulePathPatterns
[数组<字符串>]verbose
[布尔值]watchPathIgnorePatterns
[数组<字符串>]watchPlugins
[数组<字符串 | [字符串,对象]>]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 会运行所有测试并在完成时将所有错误输出到控制台。bail 配置选项可用于在 n
次失败后让 Jest 停止运行测试。将 bail 设置为 true
等同于将 bail 设置为 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。
帮助
如果您看到以下覆盖信息输出...
=============================== 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.
很可能是您的 glob 模式没有匹配任何文件。请参考 micromatch 文档以确保您的 glob 与之兼容。
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;
如果在 global
旁边指定了 glob 或路径,则匹配路径的覆盖率数据将从总体覆盖率中减去,并且阈值将独立应用。glob 的阈值应用于与 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/**/*.js
glob 匹配的文件之一的语句覆盖率低于 90%。 ./src/api/very-important-module.js
文件的覆盖率低于 100%。- 所有剩余文件组合的覆盖率低于 50% (
global
)。
dependencyExtractor
[字符串]
默认值:undefined
此选项允许使用自定义依赖项提取器。它必须是一个导出具有 extract
函数的对象的节点模块。例如
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
允许在测试运行时在测试旁边打印标签。这在存在多个 jest 配置文件的多个项目存储库中变得更加有用。这在视觉上告诉您测试属于哪个项目。
- 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
支持的所有有效颜色选项也受 Jest 支持。
- 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
和 .js
文件,其中最近的 package.json
的 type
字段设置为 module
作为 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
[对象]
默认值:{}
当一段代码设置了一个我们不想在测试中等待的长时间超时时,伪计时器可能很有用。有关更多详细信息,请参阅 伪计时器指南 和 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
[数组<字符串>]
默认值:['']
测试文件通常从收集代码覆盖率中忽略。使用此选项,您可以覆盖此行为并将原本忽略的文件包含在代码覆盖率中。
例如,如果您在名为 .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
[对象]
默认值:{}
一组需要在所有测试环境中可用的全局变量。
例如,以下操作将在所有测试环境中创建一个设置为 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
[字符串]
默认值:undefined
此选项允许使用自定义全局设置模块,该模块必须导出一个函数(可以是同步或异步的)。该函数将在所有测试套件之前触发一次,它将接收两个参数:Jest 的 globalConfig
和 projectConfig
。
在项目中配置的全局设置模块(使用多项目运行器)将仅在您从该项目运行至少一个测试时触发。
通过 globalSetup
定义的任何全局变量只能在 globalTeardown
中读取。您无法在测试套件中检索此处定义的全局变量。
虽然代码转换将应用于链接的设置文件,但 Jest 不会转换 node_modules
中的任何代码。这是因为需要加载实际的转换器(例如 babel
或 typescript
)来执行转换。
module.exports = async function (globalConfig, projectConfig) {
console.log(globalConfig.testPathPattern);
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.testPathPattern);
console.log(projectConfig.cache);
await globalThis.__MONGOD__.stop();
};
globalTeardown
[字符串]
默认值:undefined
此选项允许使用自定义全局拆卸模块,该模块必须导出一个函数(可以是同步或异步的)。该函数将在所有测试套件之后触发一次,它将接收两个参数:Jest 的 globalConfig
和 projectConfig
。
在项目中配置的全局拆卸模块(使用多项目运行器)将仅在您从该项目运行至少一个测试时触发。
与 globalSetup
相同的关于 node_modules
转换的警告也适用于 globalTeardown
。
haste
[对象]
默认值: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 on 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
[布尔值]
默认值: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
[数字]
默认值:5
一个数字,限制使用 test.concurrent
时允许同时运行的测试数量。超过此限制的任何测试都将排队并在释放插槽后执行。
maxWorkers
[数字 | 字符串]
指定工作池将为运行测试而生成的 worker 的最大数量。在单次运行模式下,这默认为您的机器上可用的核心数量减去主线程的一个。在监视模式下,这默认为您机器上可用核心的二分之一,以确保 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
[数组<字符串>]
默认值:["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;
moduleFileExtensions
[数组<字符串>]
默认值:["js", "mjs", "cjs", "jsx", "ts", "tsx", "json", "node"]
模块使用的文件扩展名数组。如果您需要模块而不指定文件扩展名,这些是 Jest 将查找的扩展名,按从左到右的顺序。
我们建议将项目中最常用的扩展名放在左侧,因此,如果您使用的是 TypeScript,您可能需要考虑将 "ts" 和/或 "tsx" 移动到数组的开头。
moduleNameMapper
[对象<字符串,字符串 | 数组<字符串>>]
默认值:null
从正则表达式到模块名称或模块名称数组的映射,允许使用单个模块来存根资源,如图像或样式。
映射到别名的模块默认情况下不会被模拟,无论是否启用了自动模拟。
使用 `<rootDir>` 字符串标记来引用 rootDir
值,如果你想使用文件路径。
此外,你可以使用编号的反向引用来替换捕获的正则表达式组。
- 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
激活测试结果的原生操作系统通知。要显示通知,Jest 需要 node-notifier
包,该包需要另外安装
- npm
- Yarn
- pnpm
npm install --save-dev node-notifier
yarn add --dev node-notifier
pnpm add --save-dev node-notifier
在 macOS 上,请记住在系统偏好设置 > 通知和焦点下允许来自 `terminal-notifier` 的通知。
在 Windows 上,`node-notifier` 在第一次使用时会在开始菜单中创建一个新的条目,而不是显示通知。在后续运行中,通知将正确显示。
notifyMode
[string]
默认值:failure-change
指定通知模式。需要 `notify: true`。
模式
always
:始终发送通知。failure
:测试失败时发送通知。success
:测试通过时发送通知。change
:状态更改时发送通知。success-change
:测试通过时发送通知,或在测试失败时发送一次通知。failure-change
:测试失败时发送通知,或在测试通过时发送一次通知。
openHandlesTimeout
[number]
默认值:1000
如果 Jest 在完成后的此毫秒数内没有干净地退出,则打印一个警告,表明可能存在打开的句柄。使用 `0` 禁用警告。
preset
[string]
默认值:undefined
用作 Jest 配置基础的预设。预设应该指向一个 npm 模块,该模块在根目录下有一个 `jest-preset.json`、`jest-preset.js`、`jest-preset.cjs` 或 `jest-preset.mjs` 文件。
例如,这个预设 `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
[string]
默认值:'prettier'
设置用于更新内联快照的 prettier
节点模块的路径。
Prettier 版本 3 不支持!
你可以在你的配置中传递 `prettierPath: null` 来禁用使用 prettier(如果你不需要它),或者只使用 Prettier 的 v2 版本用于 Jest。
{
"devDependencies": {
"prettier-2": "npm:prettier@^2"
}
}
- JavaScript
- TypeScript
/** @type {import('jest').Config} */
const config = {
prettierPath: require.resolve('prettier-2'),
};
module.exports = config;
import type {Config} from 'jest';
const config: Config = {
prettierPath: require.resolve('prettier-2'),
};
export default config;
我们希望在 Jest 的未来版本中无缝地支持 Prettier v3。请查看 此 跟踪问题。
projects
[array<string | ProjectConfig>]
默认值:undefined
当 `projects` 配置使用路径或 glob 模式数组提供时,Jest 将同时在所有指定项目中运行测试。这非常适合单体仓库或同时处理多个项目时。
- 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 实例中运行无限数量的项目。
projects 功能还可以用于运行多个配置或多个 运行器。为此,你可以传递一个配置对象数组。例如,要在同一个 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
[boolean]
默认值:false
等效于 --randomize
标志,用于随机化文件中测试的顺序。
reporters
[array<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'`,它将被启用。例如,你可能希望将其用作独立的报告程序,而不是默认报告程序,或者与 Silent Reporter 一起使用
- 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
[boolean]
默认值:false
在每次测试之前自动重置模拟状态。等效于在每次测试之前调用 jest.resetAllMocks()
。这将导致任何模拟的伪造实现被移除,但不会恢复其初始实现。
resetModules
[boolean]
默认值:false
默认情况下,每个测试文件都有自己的独立模块注册表。启用 `resetModules` 会更进一步,并在运行每个单独的测试之前重置模块注册表。这对于隔离每个测试的模块很有用,这样本地模块状态就不会在测试之间发生冲突。这可以通过使用 jest.resetModules()
以编程方式完成。
resolver
[string]
默认值:undefined
此选项允许使用自定义解析器。此解析器必须是一个模块,该模块导出以下两种方式之一
- 一个函数,第一个参数是待解析路径的字符串,第二个参数是选项对象。该函数应该返回要解析的模块的路径,或者如果找不到模块,则抛出错误。或者
- 一个包含 `async` 和/或 `sync` 属性的对象。`sync` 属性应该是一个函数,其形状如上所述,而 `async` 属性也应该是一个函数,它接受相同的参数,但返回一个 promise,该 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;
/** 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>;
/** Allows transforming parsed `package.json` contents. */
packageFilter?: (pkg: PackageJSON, file: string, dir: string) => PackageJSON;
/** Allows transforms a path within a package. */
pathFilter?: (pkg: PackageJSON, path: string, relativePath: string) => string;
/** Current root directory. */
rootDir?: string;
};
作为选项传递的 `defaultResolver` 是 Jest 默认解析器,当编写自定义解析器时,它可能很有用。它接受与你的自定义同步解析器相同的参数,例如 `(path, options)`,并返回一个字符串或抛出错误。
例如,如果你想尊重 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;
通过组合 `defaultResolver` 和 `packageFilter`,我们可以实现一个 `package.json` “预处理器”,它允许我们更改默认解析器解析模块的方式。例如,假设我们想使用 `“module”` 字段(如果存在),否则回退到 `“main”`
module.exports = (path, options) => {
// Call the defaultResolver, so we leverage its cache, error handling, etc.
return options.defaultResolver(path, {
...options,
// Use packageFilter to process parsed `package.json` before the resolution (see https://npmjs.net.cn/package/resolve#resolveid-opts-cb)
packageFilter: pkg => {
return {
...pkg,
// Alter the value of `main` before resolving the package
main: pkg.module || pkg.main,
};
},
});
};
restoreMocks
[boolean]
默认值: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 应该用来搜索文件的目录路径列表。
有时您只想让 Jest 搜索单个子目录(例如,当您的仓库中有一个 src/
目录时),但阻止它访问仓库的其余部分。
虽然 rootDir
主要用作在其他配置选项中重复使用的标记,但 roots
由 Jest 的内部机制用来定位测试文件和源文件。这也适用于搜索来自 node_modules
的模块的手动模拟(__mocks__
需要位于 roots
中的某个位置)。
默认情况下,roots
只有一个条目 <rootDir>
,但有些情况下您可能希望在一个项目中有多个根目录,例如 roots: ["<rootDir>/src/", "<rootDir>/tests/"]
。
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
[数组<字符串>]
在 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
[数组]
默认值:[]
模块路径列表,这些模块运行一些代码来配置或设置测试环境。每个 setupFile 将为每个测试文件运行一次。由于每个测试都在自己的环境中运行,因此这些脚本将在执行 setupFilesAfterEnv
和测试代码本身之前在测试环境中执行。
如果您的设置脚本是 CJS 模块,它可能会导出一个异步函数。Jest 将调用该函数并等待其结果。这可能对异步获取一些数据很有用。如果文件是 ESM 模块,只需使用顶层 await 即可获得相同的结果。
setupFilesAfterEnv
[数组]
默认值:[]
模块路径列表,这些模块运行一些代码来配置或设置测试框架,以便在执行套件中的每个测试文件之前执行。由于 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;
showSeed
[布尔值]
默认值:false
等效于 --showSeed
标志,用于在测试报告摘要中打印种子。
slowTestThreshold
[数字]
默认值:5
测试被视为缓慢并因此在结果中报告的秒数。
snapshotFormat
[对象]
默认值:{escapeString: false, printBasicPrototype: false}
允许覆盖 pretty-format 自述文件 中记录的特定快照格式选项,但 compareKeys
和 plugins
除外。例如,此配置将使快照格式化程序不为“对象”和“数组”打印前缀
- 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 元素有默认序列化器。有关更多信息,请参阅 快照测试教程。
module.exports = {
serialize(val, config, indentation, depth, refs, printer) {
return `Pretty foo: ${printer(val.foo)}`;
},
test(val) {
return val && Object.prototype.hasOwnProperty.call(val, 'foo');
},
};
printer
是一个函数,它使用现有的插件序列化一个值。
将 custom-serializer
添加到您的 Jest 配置中
- 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.js'],
};
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)
签名造成的,但这通常不会对大多数用例造成问题。
测试文件中的任何文档块标记都将传递给环境构造函数,并且可以用于每个测试的配置。如果标记没有值,它将存在于对象中,其值设置为空字符串。如果标记不存在,它将不会存在于对象中。
要将此类用作您的自定义环境,请在项目中引用其完整路径。例如,如果您的类存储在项目子文件夹中的 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://jest.node.org.cn/',
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://jest.node.org.cn/',
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://jest.node.org.cn/"}
*/
test('use jsdom and set the URL in this test file', () => {
expect(window.location.href).toBe('https://jest.node.org.cn/');
});
testFailureExitCode
[数字]
默认值:1
Jest 在测试失败时返回的退出代码。
这不会改变 Jest 错误(例如无效配置)情况下的退出代码。
testMatch
[数组<字符串>]
(默认值:[ "**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ]
)
Jest 用于检测测试文件的 glob 模式。默认情况下,它会在 __tests__
文件夹中查找 .js
、.jsx
、.ts
和 .tsx
文件,以及任何以 .test
或 .spec
为后缀的文件(例如 Component.test.js
或 Component.spec.js
)。它还会找到名为 test.js
或 spec.js
的文件。
有关您可以指定的模式的详细信息,请参阅 micromatch 包。
另请参阅 testRegex
[string | array<string>],但请注意,您不能同时指定这两个选项。
每个 glob 模式按它们在配置中指定的顺序应用。例如 ["!**/__fixtures__/**", "**/__tests__/**/*.js"]
不会排除 __fixtures__
,因为否定被第二个模式覆盖。为了使否定 glob 在此示例中起作用,它必须出现在 **/__tests__/**/*.js
之后。
testPathIgnorePatterns
[array<string>]
默认值:["/node_modules/"]
一个正则表达式模式字符串数组,在执行测试之前,这些字符串与所有测试路径匹配。如果测试路径与任何模式匹配,它将被跳过。
这些模式字符串与完整路径匹配。使用 <rootDir>
字符串标记来包含项目根目录的路径,以防止它意外忽略在可能具有不同根目录的不同环境中的所有文件。例如:["<rootDir>/build/", "<rootDir>/node_modules/"]
。
testRegex
[string | array<string>]
默认值:(/__tests__/.*|(\\.|/)(test|spec))\\.[jt]sx?$
Jest 用于检测测试文件的模式或模式。默认情况下,它会在 __tests__
文件夹中查找 .js
、.jsx
、.ts
和 .tsx
文件,以及任何以 .test
或 .spec
为后缀的文件(例如 Component.test.js
或 Component.spec.js
)。它还会找到名为 test.js
或 spec.js
的文件。另请参阅 testMatch
[array<string>],但请注意,您不能同时指定这两个选项。
以下是默认正则表达式的可视化表示
├── __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
此选项允许使用自定义结果处理器。此处理器必须是一个节点模块,它导出一个函数,该函数将具有以下结构的对象作为第一个参数并返回它
{
"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
},
...
],
"perfStats": {
"start": epoch,
"end": 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;
将 custom-sequencer
添加到您的 Jest 配置中
- 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?$/
RegExp 匹配的任何文件(换句话说,任何 .js
、.jsx
、.ts
或 .tsx
文件)。此外,babel-jest
将注入 Babel 插件,该插件对于 ES 模块模拟 中提到的模拟提升是必要的。
有关更多详细信息和有关构建您自己的转换器的说明,请参阅 代码转换 部分。
请记住,转换器每个文件只运行一次,除非文件已更改。
如果您希望将 babel-jest
转换器与其他代码预处理器一起使用,请记住显式地包含默认的 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/[email protected]/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/@[email protected]/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/@[email protected]/node_modules/@scope/pkg-b/' */
'node_modules/(?!.pnpm|package-a|@scope/pkg-b)',
],
};
export default config;
需要注意的是,.pnpm
下的 pnpm 的文件夹名称是包名加上 @
和版本号,因此写入 /
将无法识别,但使用 @
可以。
unmockedModulePathPatterns
[array<string>]
默认值:[]
一个正则表达式模式字符串数组,在模块加载器自动为它们返回模拟之前,这些字符串与所有模块匹配。如果模块的路径与此列表中的任何模式匹配,则模块加载器不会自动对其进行模拟。
这对于一些常用的“实用程序”模块很有用,这些模块几乎总是作为实现细节使用(例如 underscore
、lodash
等)。通常,最佳做法是尽可能缩短此列表,并在单个测试中始终使用显式的 jest.mock()
/jest.unmock()
调用。显式的每个测试设置对于测试的其他读者来说更容易理解测试将在其中运行的环境。
可以通过在测试文件顶部显式调用 jest.mock()
来覆盖单个测试中的此设置。
verbose
[boolean]
默认值:false
或 true
(如果只有一个测试文件要运行)
指示在运行期间是否应报告每个单独的测试。所有错误也将在执行后显示在底部。
watchPathIgnorePatterns
[array<string>]
默认值:[]
一个 RegExp 模式数组,在监视模式下重新运行测试之前,这些模式与所有源文件路径匹配。如果文件路径与任何模式匹配,则更新时,它不会触发测试的重新运行。
这些模式与完整路径匹配。使用 <rootDir>
字符串标记来包含项目根目录的路径,以防止它意外忽略可能在不同环境中具有不同根目录的所有文件。示例:["<rootDir>/node_modules/"]
。
即使这里没有指定任何内容,观察者也会忽略对版本控制文件夹(.git、.hg、.sl)的更改。其他隐藏文件和目录(即以点 (.
) 开头的文件和目录)默认情况下会被监视。请记住,当您将它们添加到 watchPathIgnorePatterns
中时,请转义点,因为它是一个特殊的 RegExp 字符。
- 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
[array<string | [string, Object]>]
默认值:[]
此选项允许您使用自定义监视插件。阅读有关监视插件的更多信息 此处。
监视插件的示例包括
jest-watch-master
jest-watch-select-projects
jest-watch-suspend
jest-watch-typeahead
jest-watch-yarn-workspaces
watchPlugins
属性值中的值可以省略包名称的 jest-watch-
前缀。
watchman
[boolean]
默认值:true
是否使用 watchman
进行文件爬取。
workerIdleMemoryLimit
[number|string]
默认值:undefined
指定工作程序在回收之前内存限制,主要用于解决 此问题;
工作程序执行完测试后,会检查它的内存使用情况。如果超过指定的值,工作程序将被杀死并重新启动。限制可以用多种方式指定,无论结果如何,Math.floor
都用于将其转换为整数值
<= 1
- 假设该值为系统内存的百分比。因此,0.5 将工作程序的内存限制设置为系统总内存的一半\> 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;
//
[string]
此选项允许在 package.json
中使用注释。将注释文本作为此键的值包含在内
{
"name": "my-project",
"jest": {
"//": "Comment goes here",
"verbose": true
}
}
workerThreads
默认值:false
使用工作线程可能有助于提高 性能。
这是一个 实验性功能。请记住,工作线程使用结构化克隆而不是 JSON.stringify()
来序列化消息。这意味着内置的 JavaScript 对象,如 BigInt
、Map
或 Set
将被正确序列化。但是,在 Error
、Map
或 Set
上设置的额外属性将不会通过序列化步骤传递。有关更多详细信息,请参阅有关 结构化克隆 的文章。