跳至主要內容
版本:29.7

疑難排解

糟糕,出問題了嗎?請使用此指南來解決 Jest 的問題。

測試失敗,而您不知道原因

嘗試使用內建於 Node 的 除錯支援。在任何測試中放置 debugger; 陳述式,然後在專案目錄中執行

node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here]
or on Windows
node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand [any other arguments here]

這會在外部除錯器可以連線的 Node 程序中執行 Jest。請注意,此程序會暫停,直到除錯器已連線為止。

要在 Google Chrome(或任何基於 Chromium 的瀏覽器)中除錯,請開啟瀏覽器並前往 chrome://inspect,然後按一下「為 Node 開啟專用 DevTools」,這將提供您可以連線的可用節點執行個體清單。按一下執行上述指令後終端機中顯示的位址(通常類似於 localhost:9229),您將可以使用 Chrome 的 DevTools 除錯 Jest。

Chrome 開發人員工具將會顯示,且中斷點將設定在 Jest CLI 腳本的第一行(此舉是為了讓您有時間開啟開發人員工具,並防止 Jest 在您有時間執行之前執行)。按一下螢幕右上角看起來像「播放」按鈕的按鈕,繼續執行。當 Jest 執行包含 debugger 陳述式的測試時,執行將暫停,您可以檢查目前的範圍和呼叫堆疊。

註解

--runInBand cli 選項確保 Jest 在同一個程序中執行測試,而不是為個別測試產生程序。通常,Jest 會在程序中並行化測試執行,但同時偵錯多個程序很困難。

在 VS Code 中偵錯

有多種方法可以用 Visual Studio Code 內建的 偵錯器 偵錯 Jest 測試。

若要附加內建偵錯器,請如前所述執行您的測試

node --inspect-brk node_modules/.bin/jest --runInBand [any other arguments here]
or on Windows
node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand [any other arguments here]

然後使用下列 launch.json 設定附加 VS Code 的偵錯器

{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach",
"port": 9229
}
]
}

若要自動啟動並附加到執行測試的程序,請使用下列設定

{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/.bin/jest",
"--runInBand"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}

或使用下列設定適用於 Windows

{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Jest Tests",
"type": "node",
"request": "launch",
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/jest/bin/jest.js",
"--runInBand"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}

如果您使用 Facebook 的 create-react-app,您可以使用下列設定偵錯您的 Jest 測試

{
"version": "0.2.0",
"configurations": [
{
"name": "Debug CRA Tests",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
"args": [
"test",
"--runInBand",
"--no-cache",
"--env=jsdom",
"--watchAll=false"
],
"cwd": "${workspaceRoot}",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}

可以在 這裡 找到更多關於 Node 偵錯的資訊。

在 WebStorm 中進行偵錯

WebStorm 內建支援 Jest。閱讀 在 WebStorm 中使用 Jest 進行測試 以深入了解。

快取問題

轉換指令碼已變更或 Babel 已更新,而 Jest 沒有辨識到變更?

使用 --no-cache 重試。Jest 會快取已轉換的模組檔案,以加快測試執行速度。如果您使用自己的自訂轉換器,請考慮為其新增 getCacheKey 函數:Relay 中的 getCacheKey

未解決的 Promise

如果 Promise 完全沒有解決,可能會擲出此錯誤

- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.`

最常見的原因是 Promise 實作衝突。請考慮將全域 Promise 實作替換為您自己的實作,例如 globalThis.Promise = jest.requireActual('promise'); 和/或將使用的 Promise 函式庫合併為單一函式庫。

如果您的測試執行時間很長,您可能需要考慮透過呼叫 jest.setTimeout 來增加逾時時間

jest.setTimeout(10_000); // 10 second timeout

Watchman 問題

嘗試使用 --no-watchman 執行 Jest,或將 watchman 設定選項設為 false

另請參閱 Watchman 疑難排解

在 Docker 和/或持續整合 (CI) 伺服器上,測試極為緩慢。

雖然 Jest 在配備快速 SSD 的現代多核心電腦上大部分時間都非常快速,但它在某些設定上可能會很慢,正如我們的使用者 發現

根據 調查結果,減輕此問題並將速度提升至 50% 的一種方法是依序執行測試。

為此,您可以使用 --runInBand 在同一個執行緒中執行測試

# Using Jest CLI
jest --runInBand

# Using your package manager's `test` script (e.g. with create-react-app)
npm test -- --runInBand

加速連續整合伺服器(例如 Travis-CI)上測試執行時間的另一種替代方法是將最大工作池設定為 ~4。特別是在 Travis-CI 上,這可以將測試執行時間減半。注意:Travis CI 免費方案僅提供給開放原始碼專案,且僅包含 2 個 CPU 核心。

# Using Jest CLI
jest --maxWorkers=4

# Using your package manager's `test` script (e.g. with create-react-app)
npm test -- --maxWorkers=4

如果您使用 GitHub Actions,可以使用 github-actions-cpu-cores 偵測 CPU 數量,並將其傳遞給 Jest。

- name: Get number of CPU cores
id: cpu-cores
uses: SimenB/github-actions-cpu-cores@v2
- name: run tests
run: yarn jest --max-workers ${{ steps.cpu-cores.outputs.count }}

您還可以做的是使用 shard 旗標在多部機器上並行執行測試。

coveragePathIgnorePatterns 似乎沒有任何作用。

請確定您沒有使用 babel-plugin-istanbul 外掛程式。Jest 會封裝 Istanbul,因此也會告訴 Istanbul 要使用哪些檔案進行覆蓋範圍收集。當使用 babel-plugin-istanbul 時,每個由 Babel 處理的檔案都會有覆蓋範圍收集程式碼,因此不會被 coveragePathIgnorePatterns 忽略。

定義測試

測試必須同步定義,Jest 才可以收集您的測試。

舉例來說明原因,假設我們撰寫了一個如下所示的測試

// Don't do this it will not work
setTimeout(() => {
it('passes', () => expect(1).toBe(1));
}, 0);

當 Jest 執行您的測試以收集 test 時,它找不到任何測試,因為我們已將定義設定為在事件迴圈的下一個滴答聲中非同步執行。這表示當您使用 test.each 時,您無法在 beforeEach / beforeAll 中非同步設定表格。

仍未解決?

請參閱 說明