Jest 插件
插件包 | @rushstack/heft-jest-plugin |
插件名称 | jest-plugin 由 JestPlugin.ts 实现 |
插件配置文件 | Jest 的 jest.config.json 由 @rushstack/heft-config-file 加载用于 rigging |
heft.json 选项 | IJestPluginOptions |
此插件调用 Jest 测试框架进行单元测试。
何时使用它
我们推荐 Jest 有以下几个原因
一体化:与
mocha
等需要多个组件组合在一起的框架不同,Jest 为您的测试运行器、断言库、模拟/间谍 API、代码检测、代码覆盖率和报告提供了单一的集成解决方案。Jest 还对 React 提供一流的支持。交互式:Jest 支持“监视模式”,以便在保存文件时自动重新运行测试,以及 快照测试,当合约发生变化时可以自动更新断言。
隔离的运行时:Jest 在 Node.js 环境中运行 Web 测试,而不是启动 Web 浏览器,并利用 Node.js VM 功能来防止测试泄漏状态。
也就是说,如果你出于某种原因需要在其他运行时(如 Android 客户端或真实的 Web 浏览器)中运行测试,Jest 可能不是最佳选择。
package.json 依赖项
如果您使用的是标准 rig,例如 @rushstack/heft-node-rig 或 @rushstack/heft-web-rig,那么 Jest 已经加载并配置好了。
否则,您需要将插件包添加到您的项目中
- Rush
- NPM
# If you are using Rush, run this shell command in your project folder:
rush add --package @rushstack/heft-jest-plugin --dev
# If you are using vanilla NPM, run this shell command in your project folder:
npm install @rushstack/heft-jest-plugin --save-dev
该插件直接依赖于它需要的 Jest 包,因此您无需将 Jest 添加到项目的 package.json 文件中。
您的项目应该从 @types/heft-jest
而不是 @types/jest
获取类型定义
- Rush
- NPM
# If you are using Rush, run this shell command in your project folder:
rush add --package @types/heft-jest --dev --exact
# Because @types packages don't follow SemVer, it's a good idea to use --exact
# If you are using vanilla NPM, run this shell command in your project folder:
npm install @types/heft-jest --save-dev --save-exact
# Because @types packages don't follow SemVer, it's a good idea to use --save-exact
...然后在您的 tsconfig.json 文件中引用 @types/heft-jest
,例如
{
"extends": "./node_modules/@rushstack/heft-node-rig/profiles/default/tsconfig-base.json",
"compilerOptions": {
"types": [
"heft-jest", // <---- ADD THIS
"node"
]
}
}
配置
如果 Jest 没有由 rig 提供,则您的 heft.json 配置文件 可以像此示例一样调用它
<项目文件夹>/config/heft.json
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json",
"phasesByName": {
"build": {
. . .
},
"test": {
"phaseDependencies": ["build"],
"tasksByName": {
"jest": {
"taskPlugin": {
"pluginPackage": "@rushstack/heft-jest-plugin"
}
}
}
}
}
}
Heft 在标准路径 config/jest.config.json 中查找 Jest 的配置文件。虽然 Jest 本身支持其他配置文件名,甚至在 package.json 文件中嵌入设置,但 Heft 需要 config/jest.config.json
名称。在大型单体代码库中,强制使用一个标准文件名可以更容易地搜索这些文件,执行批量编辑以及在项目之间复制配置方案。
对于简单的设置,您的 Jest 配置应该扩展 Heft 的 jest-shared.config.json,例如
<项目文件夹>/config/jest.config.json
{
"extends": "@rushstack/heft-jest-plugin/includes/jest-shared.config.json"
}
或者,如果您使用的是 rig 包,例如 @rushstack/heft-web-rig
,请指定 rig,例如
<项目文件夹>/config/jest.config.json
{
"extends": "@rushstack/heft-web-rig/profiles/library/config/jest.config.json"
}
(如果您维护自己的 rig,它应该从 @rushstack/heft-jest-plugin
扩展,以确保 Jest 使用 Heft 的转换器和解析器。)
注意:如果您发现自己经常向 jest.config.json 添加大量自定义设置,请创建一个 GitHub 问题并告诉我们。我们的目标是提供一种配置,最大程度地减少对项目特定定制的需求。
“extends” 字段
jest.config.json 中的 "extends"
字段是 Heft 特定的增强功能,如果 Jest 命令行在没有 Heft 的情况下调用,则不会起作用。此设置取代了 Jest 的 "preset"
字段,该字段的模块解析能力有限,不支持 rig。Heft 使用 @rushstack/heft-config-file
引擎解析 jest.config.json,完全支持 属性继承指令。
如果出于某种原因您的 jest.config.json
需要直接可读,则可以使用 disableConfigurationModuleResolution
插件设置来恢复标准行为,缺点是您的 Jest 配置将不可 rigging。
例如
<项目文件夹>/config/heft.json
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json",
"phasesByName": {
"build": {
. . .
},
"test": {
"phaseDependencies": ["build"],
"tasksByName": {
"jest": {
"taskPlugin": {
"pluginPackage": "@rushstack/heft-jest-plugin",
"options": {
// (Not recommended) Disable Heft's support for rigs and the "extends" field
"disableConfigurationModuleResolution": true
}
}
}
}
}
}
}
与 ts-jest 的区别
按照惯例,Jest 通过名为 转换器 的插件来支持 TypeScript 编译,这些插件被建模为接收单个 .ts
文件作为输入,并返回 .js
文件和 .map
文件作为输出。官方的 babel-jest
转换器实际上确实一次编译一个文件,但这种方法不支持 const enum
等需要分析导入类型的语言特性。流行的 ts-jest
转换器通过执行完整的编译器分析并在每次调用转换器时重复使用它来解决这个问题,但这不支持其他构建步骤,例如预处理器。babel-jest
和 ts-jest
还会通过在运行测试时再次调用编译器来产生重大的性能成本。
Heft 采取了不同的方法,执行传统的构建,然后对输出调用 Jest。如果您的构建目标是浏览器运行时,您需要使用 additionalModuleKindsToEmit 设置在辅助文件夹中发出 CommonJS 输出。(发出额外文件仍然比两次调用编译器快得多。)除了避免冗余的编译器调用,Heft 的策略确保您的单元测试使用您的完整构建过程进行编译,包括任何预处理任务,例如 Sass 类型生成。
在 heft-node-jest-tutorial 项目文件夹中可以找到一些关于模拟和其他 Jest 技术的有用示例。
使用 Jest 与 Heft 时的一些重要区别
使用
heft
命令行调用 Jest。直接调用jest
命令行不会调用 TypeScript,并且与 jest.config.json 中的"extends"
字段不兼容。不要将
ts-jest
或babel-jest
作为项目的依赖项添加。不要使用
import { mocked } from "ts-jest/utils";
,而是使用由@types/heft-jest
提供的全局mocked()
函数。除了这个区别,ts-jest
的 API 文档 仍然适用于 Heft 的实现。
ts-jest
转换器将神奇地“提升”对jest.mock();
的调用。Heft 并不认为这是最佳实践。相反,请使用 @rushstack/hoist-jest-mock lint 规则来提醒开发人员手动提升他们的调用。它默认启用,使用 @rushstack/eslint-config。
调试 Jest 测试
要调试您的 Jest 测试,建议创建 VS Code launch.json 文件,例如
<项目文件夹>/.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Jest tests",
"program": "${workspaceFolder}/node_modules/@rushstack/heft/lib/start.js",
"cwd": "${workspaceFolder}",
"args": ["--debug", "test", "--clean"],
"console": "integratedTerminal",
"sourceMaps": true
},
]
}
这会在您的调试器中启动完整的 Heft 工具链。--debug
开关会阻止 Jest 作为单独的进程生成。--clean
标志是可选的,但会修复在罕见情况下 Jest 的“haste-map”可能会因运行中止而损坏的问题。
要将调试器限制为运行一个特定的测试,您可以添加 --test-name-pattern
参数。(有关命令行文档,请参阅 此处。)另一个选择是使用 Jest 的 test.only() API。
CLI 参数
heft-jest-plugin/heft-plugin.json 定义了这些参数
--config RELATIVE_PATH
Use this parameter to control which Jest
configuration file will be used to run Jest tests. If
not specified, it will default to "config/jest.config.
json". This corresponds to the "--config" parameter
in Jest's documentation.
--debug-heft-reporter
Normally Heft installs a custom Jest reporter so that
test results are presented consistently with other
task logging. If you suspect a problem with the
HeftJestReporter, specify "--debug-heft-reporter" to
temporarily disable it so that you can compare with
how Jest's default reporter would have presented it.
Include this output in your bug report. Do not use
"--debug-heft-reporter" in production.
--detect-open-handles
Attempt to collect and print open handles preventing
Jest from exiting cleanly. This option has a
significant performance penalty and should only be
used for debugging. This corresponds to the
"--detectOpenHandles" parameter in Jest's
documentation.
--disable-code-coverage
Disable any configured code coverage. If code
coverage is not configured, this parameter has no
effect.
--find-related-tests SOURCE_FILE
Find and run the tests that cover a source file that
was passed in as an argument. This corresponds to the
"--findRelatedTests" parameter in Jest's
documentation. This parameter is not compatible with
watch mode.
--max-workers COUNT_OR_PERCENTAGE
Use this parameter to control maximum number of
worker processes tests are allowed to use. This
parameter is similar to the parameter noted in the
Jest documentation, and can either be an integer
representing the number of workers to spawn when
running tests, or can be a string representing a
percentage of the available CPUs on the machine to
utilize. Example values: "3", "25%"
--silent
Prevent tests from printing messages through the
console. This corresponds to the "--silent" parameter
in Jest's documentation.
-t REGEXP, --test-name-pattern REGEXP
Run only tests with a name that matches a regular
expression. The REGEXP is matched against the full
name, which is a combination of the test name and all
its surrounding describe blocks. This corresponds to
the "--testNamePattern" parameter in Jest's
documentation.
--test-path-ignore-patterns REGEXP
Avoid running tests with a source file path that
matches one ore more regular expressions. On Windows
you will need to use "/" instead of "\". This
corresponds to the "--testPathIgnorePatterns"
parameter in Jest's documentation.
--test-path-pattern REGEXP
Run only tests with a source file path that matches a
regular expression. On Windows you will need to use
"/" instead of "\". This corresponds to the
"--testPathPattern" parameter in Jest's documentation.
--test-timeout-ms TIMEOUT
Change the default timeout for tests; if a test
doesn't complete within this many milliseconds, it
will fail. Individual tests can override the default.
If unspecified, the default is normally 5000 ms. This
corresponds to the "--testTimeout" parameter in
Jest's documentation.
-u, --update-snapshots
Update Jest snapshots while running the tests. This
corresponds to the "--updateSnapshots" parameter in
Jest.
heft.json 插件选项
在您的 heft.json 中加载 @rushstack/heft-jest-plugin
时,可以使用 "options"
字段提供以下设置,这些设置可以内联提供
heft-plugins/heft-jest-plugin/src/JestPlugin.ts
export interface IJestPluginOptions {
configurationPath?: string;
debugHeftReporter?: boolean;
detectOpenHandles?: boolean;
disableCodeCoverage?: boolean;
disableConfigurationModuleResolution?: boolean;
findRelatedTests?: string[];
maxWorkers?: string;
passWithNoTests?: boolean;
silent?: boolean;
testNamePattern?: string;
testPathIgnorePatterns?: string;
testPathPattern?: string;
testTimeout?: number;
updateSnapshots?: boolean;
}
它们的功能与相应的命令行参数相同。
另请参阅
- heft-node-jest-tutorial 示例项目
- Jest 的 API 参考
- jest.config.json 文档