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 環境中執行網路測試,而非啟動網路瀏覽器,並利用 Node.js VM 功能,以防止測試遺漏狀態。
話雖如此,如果您出於某些原因需要在其他執行時期(如 Android 應用程式或真實網路瀏覽器)中執行測試,Jest 可能並非最佳選擇。
package.json 相依性
如果您使用標準裝置,例如 @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 尚未由裝置提供,您的 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
。在大型 monorepo 中,強制執行一個標準檔名能更輕鬆地在這些檔案中進行搜尋、執行大量編輯,以及複製專案之間的組態食譜。
對於簡單的設定,您的 Jest 組態應延展 Heft 的 jest-shared.config.json,如下所示
<專案資料夾>/config/jest.config.json
{
"extends": "@rushstack/heft-jest-plugin/includes/jest-shared.config.json"
}
或者,如果您使用裝置套件,例如 @rushstack/heft-web-rig
,指定裝置,如下範例所示
<專案資料夾>/config/jest.config.json
{
"extends": "@rushstack/heft-web-rig/profiles/library/config/jest.config.json"
}
(如果您維護自己的裝置,它應從 @rushstack/heft-jest-plugin
延展,以確保 Jest 使用 Heft 的轉換器和解析器。)
注意事項:如果您發現自己經常將大量自訂設定新增至 jest.config.json,請建立一個 GitHub 議題並告訴我們。我們的目標是提供一個組態,將專案特定自訂設定的需求降至最低。
“extends” 欄位
jest.config.json 中的 “extends”
欄位是 Heft 特有的擴充功能,如果在沒有 Heft 的情況下呼叫 Jest 命令列,此功能將無法運作。此設定會取代 Jest 的 “preset”
欄位,後者的模組解析能力有限,且不支援裝置。Heft 使用 @rushstack/heft-config-file
引擎解析 jest.config.json,並完全支援 屬性繼承指令。
如果因為某些原因您的 jest.config.json
需要由 Jest 直接讀取,可以使用外掛設定 disableConfigurationModuleResolution
還原標準行為,但缺點是您的 Jest 組態將無法安裝裝置。
例如
<專案資料夾>/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 編譯,將該外掛建模為一個函式,它接收單一的程式碼檔案作為輸入,並回傳一個程式碼檔案和地圖檔作為其輸出。正式的 babel-jest
轉換實際上會一次編譯一個檔案,但是這種方法無法支援需要分析匯入類型等語言功能,例如 const enum
。常見的 ts-jest
轉換透過執行完整的編譯器分析並在每次呼叫轉換時重複使用它來解決這個問題,但是這無法支援其他建置步驟,例如預處理器。babel-jest
和 ts-jest
都會在執行測試時重複呼叫編譯器,對效能造成顯著的影響。
Heft 採用一種不同的方法,執行傳統建置然後在輸出的檔案上呼叫 Jest。如果您的建置針對瀏覽器執行時期,您需要使用 additionalModuleKindsToEmit 設定,才能在次要資料夾中輸出 CommonJS 輸出檔案。(輸出額外的檔案仍比重複呼叫編譯器快上許多。)除了避免重複的編譯器呼叫外,Heft 的策略確保您的單元測試會搭配完整的建置流程一起編譯,包括任何預處理器任務,例如 Sass 類型產生。
可以在 heft-node-jest-tutorial 專案資料夾中找到一些有用的範例,說明如何模擬和其他 Jest 技術。
在 Heft 中使用 Jest 時的重要差異
使用
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 檢查規則,提醒開發人員手動提升他們的呼叫。它預設已由 @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。
命令列參數
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 文件