前言
Jest 是我第一個接觸的測試框架。在接觸 Jest 之前,測試程式其實都是手動去測試的,沒有想過這個過程可以自動化,節省了不少測試的時間。
什麼是 Jest
Jest 是個 JavaScript 的測試框架,目前由 Meta 維護,目地就是自動化測試程式結果是不是符合預期。提供大部分常用框架的支援,並且預設設定就可以完成大部分測試,非常好上手。
基礎使用
Jest 需求
- Node.js
- 一個 Node.js 專案
<aside> 💡 以下套件管理部分皆以 yarn
為例,如果沒有 yarn,請透過以下其中一個指令安裝
- node.js ≥ 16.10 (包含在內建的 corepack 內,需自行啟用):
corepack enable
Corepack 是 Node.js 內建的實驗性功能,直接透過 Node.js 管理套件管理工具,而不用自行管理,目前支援yarn
和pnpm
,啟用後即可直接使用,不需另外安裝 Corepack 內鑑於 Node.js 16.10 以上的版本如果您想要在 16.10 以下也使用 corepack,則需另外安裝:npm i -g corepack
相關資訊: Corepack | Node.js v18.9.1 Documentation - node.js < 16.10:
npm i -g yarn@latest
</aside>
從 0 開始撰寫第一個測試
- 以預設值建立 Node.js 專案(以下皆以 yarn 為例)
yarn init -y
- 撰寫 Javascript 程式
index.js
const plus = (a, b) => { return a + b; } module.exports = plus;
<aside> ⚠️ 檔案需要被 export 才能被測試框架接收並測試 本範例將要被測試的程式寫成一個含式,並透過下面那行程式匯出來給 Jest 使用module.exports = plus;
</aside> - 可以先手動測試一下他的效果
- 在終端機中,輸入
node
進入 Node.js 的即時運算模式,此時畫面應該長這樣 - 將剛剛寫的含式引進來
const plus = require("./index");
- 此時可以透過以下指令測試
plus
含式plus(1, 1);
<aside> 💡 如果輸出和以下截圖一樣,就可以繼續下一步</aside>
- 按下
Ctrl + D
離開 Node.js 即時運算模式
- 在終端機中,輸入
<aside> 👉 此時您已經完成了主程式撰寫以及手動測試,不過現在強調的是自動化測試,接下來開始介紹如何寫測試檔
</aside>
- 安裝 Jest
yarn add jest --dev
- 建立測試檔
index.test.js
<aside> 💡 Jest 預設執行測試時會尋找檔名包含.test.
的檔案然後執行 </aside>const plus = require("./index"); test("plus(1, 1) 應該要等於 2", () => { expect(plus(1, 1)).toBe(2); })
<aside> 💡 程式碼說明:- 寫上測試描述
test(<測試描述>, <測試程式>)
test("plus(1, 1) 應該要等於 2", () => { })
- 在測試程式區塊寫上程式預期結果
expect(<要測試的含式>).toBe(<預期的輸出值>)
expect(plus(1, 1)).toBe(2);
這段代表「我預期plus(1, 1)
的回傳值是2
」,如果這段程式成立代表測試成功
- 寫上測試描述
- 執行測試
yarn jest
<aside> 💡 如果輸出長得跟下面截圖一樣,恭喜你完成第一個測試</aside>
- 製造一個不通過的測試
- 修改
index.js
,把剛剛的+
改成*
- 此時再執行一次測試,你就會發現他出錯了
<aside> 💡 解讀錯誤訊息:
- 他會說哪個測試出錯,此時剛才寫的描述會寫在這裡
- 然後會說哪一行測試失敗,例如這個例子:
因為先前在測試中寫了「預期
plus(1, 1)
的回傳值為2
」expect(plus(1, 1)).toBe(2);
但是他的實際結果卻收到了1
這個預期條件不成立了,因此他判定這個測試是失敗的。
- 他會說哪個測試出錯,此時剛才寫的描述會寫在這裡
- 修改
相關說明:
VSCode 插件 – Jest
在講其他功能之前,先來介紹一個 VsCode 的插件。
Jest – Visual Studio Marketplace
這個插件將 Jest 整合到 VSCode 內,重點功能如下:
- **自動執行測試:**預設設定下存檔時就會直接執行測試
- **直接查看測試結果:**程式碼左邊會提示目前這個測試試否成功
- **測試概觀檢視:**在左側邊欄查看所有測試狀態
其他測試語法
- 值相等 剛剛使用過的
expect(<要測試的含式>).toBe(<預期的輸出值>)
,也是最簡單的,就是檢查兩邊是否相等test("except-tobe", () => { const value = 1 + 1; expect(value).toBe(2); expect(value).not.toBe(3); })
<aside> 💡 任何測試語法都可以加上.not
代表否定判斷,例如以下測試語法會通過測試:expect(1 + 1).not.toBe(3);
</aside> - 物件值相等
.toBe
使用的是Object.is
,也就是說只要兩邊都是 Object 測試就會通過,不會管內容是否相等,因此 Jest 會檔下來不給執行test("except-tobe", () => { const value = { a:1, b:2 }; expect(value).toBe({ a:1, b:2 }); })
因此要判斷物件內容是否相等時,需使用
toEqual
test("except-toEqual", () => { const value = { a:1, b:2 }; expect(value).toEqual({ a:1, b:2 }); })
- 真假空測試 有時候,您想明確分辨
undefined
、null
跟false
,但有時候你又不想這麼明確的分辨他。此時 Jest 提供了一系列語法供使用toBeNull
:只有null
會通過toBeUndefined
:只有undefined
會通過toBeDefined
:toBeUndefined
的相反toBeTruthy
: 只要在if
內覺得是 true 的就會通過toBeFalsy
: 只要在if
內覺得是 false 的就會通過
test("null", () => { const n = null; expect(n).toBeNull(); // n 為 null,因此 toBeNull 通過 expect(n).toBeDefined(); // n 不是 undefined,因此 toBeDefined 通過 expect(n).not.toBeUndefined(); // n 不是 undefined,因此 not toBeUndefined 通過 expect(n).not.toBeTruthy(); // if (n) 視為 false,因此 not toBeTruthy 通過 expect(n).toBeFalsy(); // if (n) 視為 false,因此 toBeFalsy 通過 }); test("zero", () => { const z = 0; expect(z).not.toBeNull(); // z 不是 null,因此 not toBeNull 通過 expect(z).toBeDefined(); // z 不是 undefined,因此 toBeDefined 通過 expect(z).not.toBeUndefined(); // z 不是 undefined,因此 not toBeUndefined 通過 expect(z).not.toBeTruthy(); // if (z) 視為 false,因此 not toBeTruthy 通過 expect(z).toBeFalsy(); // if (z) 視為 false,因此 toBeFalsy 通過 });
- 數字測試
- 數字測試比較
test('two plus two', () => { const value = 2 + 2; expect(value).toBeGreaterThan(3); // 2 + 2 > 3 --> 通過 expect(value).toBeGreaterThanOrEqual(3.5); // 2 + 2 >= 3.5 --> 通過 expect(value).toBeLessThan(5); // 2 + 2 < 5 --> 通過 expect(value).toBeLessThanOrEqual(4.5); // 2 + 2 <= 4.5 --> 通過 // toBe 和 toEqual 在數字比較上是相同的 expect(value).toBe(4); expect(value).toEqual(4); });
- 為了避免踩到 JavaScript 在浮點數上的雷,例如:
會導致以下的測試無法通過
test("adding floating point numbers", () => { const value = 0.1 + 0.2; expect(value).toBe(0.3); // 0.1 + 0.2 不會等於 0.3,因此不會通過 });
因此 Jest 提供了
toBeCloseTo
,只要相似就會通過test("adding floating point numbers", () => { const value = 0.1 + 0.2; expect(value).toBeCloseTo(0.3); // 0.1 + 0.2 近似於 0.3,因此會通過 });
- 數字測試比較
- 字串比對 可以透過
toMatch
使用正規表達式(Regex)比對字串test('there is no I in team', () => { expect('team').not.toMatch(/I/); }); test('but there is a "stop" in Christoph', () => { expect('Christoph').toMatch(/stop/); });
- 陣列比對 可以使用
.toContain
檢查項目是否在 list 內const list = ["a", "b", "c", "f"]; test("the shopping list has milk on it", () => { expect(list).toContain("f"); expect(list).not.toContain("d"); });
相關說明:
ES6 測試(Babel)
<aside> 💡 Babel 官網
Babel · The compiler for next generation JavaScript
</aside>
假設現在有一個簡單的 babel 專案:
下載解壓縮後記得先執行一次 yarn
安裝相依,資料夾結構應該長這樣:

- 安裝測試用套件
yarn add jest babel-jest --dev
- 設定 babel之前,需要先把設定檔格式換成
.js
- 將
babel.config.json
重新命名成babel.config.js
- 在第一個大刮號前面加上
module.exports =
完整檔案如下:module.exports = { "presets": ["@babel/preset-env"] }
- 將
- 在設定中,將
"@babel/preset-env"
取代成['@babel/preset-env', {targets: {node: 'current'}}]
module.exports = { presets: [["@babel/preset-env", { targets: { node: "current" } }]], };
- 建立測試專用資料夾(推薦)
- 建立
index.test.js
開始寫測試,直接使用 ES6 語法即可import { plus, minus } from '../src/index'; test("plus(1, 1) 應該要等於 2", () => { expect(plus(1, 1)).toBe(2); }); test("minus(1, 1) 應該要等於 0", () => { expect(minus(1, 1)).toBe(0); });
相關說明:
TypeScript 測試
<aside> 💡 TypeScript 官網
JavaScript With Syntax For Types.
</aside>
假設現在有一個簡單的 TypeScript 專案:
下載解壓縮後記得先執行一次 yarn
安裝相依,資料夾結構應該長這樣:

- 安裝測試用套件
yarn add jest ts-jest --dev
- 到
tsconfig.json
加上這一段來忽略測試檔~~(讓 VsCode 閉嘴一下)~~,因為他不需要被編譯:"exclude": ["**/*.test.ts"]
Is there such an tsconfig option such as exclude from compiling but not from linting ?
- 生成 jest 設定檔以讓 jest 自動使用 ts-jest 引擎
yarn ts-jest config:init
- 建立測試專用資料夾(推薦)
- 建立
index.test.ts
開始寫測試,直接使用 TypeScript 語法即可 <aside> ⚠️ 注意第一行是必須被引入的,因為 TypeScript 需要型態定義 </aside>import { expect, test } from '@jest/globals'; import { plus, minus } from '../src/index'; test("plus(1, 1) 應該要等於 2", () => { expect(plus(1, 1)).toBe(2); }); test("minus(1, 1) 應該要等於 0", () => { expect(minus(1, 1)).toBe(0); });
相關說明:
常用框架測試
<aside> 💡 以下教學皆以使用工具建立的空白專案為例
</aside>
Express.js
<aside> 💡 建立 Express.js 空白專案
</aside>
<aside> 💡 如果您的 express 專案是單頁式的,例如:app.js
的 listen 跟其他程式在同一頁
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
您需要先把 listen 分離,才能進行測試,例如上面的檔案改寫成兩個程式(檔名自取):
app.js
– 主程式const express = require('express') const app = express() app.get('/', (req, res) => { res.send('Hello World!') }) module.exports = app;
server.js
– 啟動器const app = require("./app"); const port = 3000 app.listen(port , () => { console.log(`Example app listening on port ${port}`) });
正式執行時改執行 server.js
即可
</aside>
- 安裝測試用套件
yarn add jest supertest --dev
- 建立測試專用資料夾(推薦)
- 以內建的範例檔快速寫一個測試
const request = require("supertest"); // Express.js 測試程式 const app = require("../app"); // Express 主程式 describe("Test /uesrs", () => { test("It should response the GET method", () => { return request(app) .get("/users") // 呼叫 GET /users .expect(200) // 預期回傳碼為 200 .then((response) => { expect(response.text).toMatch(/resource/); // 預期回傳文字包含 resource }); }); });
<aside> 💡 因為範例檔案回傳的是存文字res.send('respond with a resource');
因此判斷內容使用response.text
但常見的 API 回應是使用 json 格式,例如:res.status(200).json({ message: 'respond with a resource' });
那回應的內容會放在response.body
內,因此測試會寫成return request(app) .get("/users") .expect(200) .then((response) => { // 預期回傳的物件路徑包含 resource expect(response.body.message).toMatch(/resource/); });
</aside>
其他說明可參考:
How to test Express.js with Jest and Supertest
React.js
<aside> 💡 建立空白的 React.js 專案
Create a New React App – React
</aside>
React.js 在建立之後就已經內建一個測試檔案了,在 src/App.test.js

內容如下:
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />); // 渲染 App 頁面
const linkElement = screen.getByText(/learn react/i); // 透過文字尋找元件
expect(linkElement).toBeInTheDocument(); // 預期元件有在網頁內
});
其他說明可參考:
Vue.js
<aside> 💡 建立空白 Vue.js 專案
</aside>
Vue 也有內建單元測試,可以在建立專案的時候選擇安裝,如果是現有 Vue 專案,在建立時沒有選擇測試元件,也可以手動安裝
新增 Vue 測試元件,有以下兩種方式:
- 建立專案時選擇安裝,在第一個選項需選擇
Manually select features
- 在現有專案手動安裝
vue add unit-jest
新增完之後會出現一些檔案,包括設定和一個範例測試檔

example.spec.js
內容如下:
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
const wrapper = shallowMount(HelloWorld, {
props: { msg }
})
expect(wrapper.text()).toMatch(msg) // 預期元件內的文字包含傳進去的 msg
})
})
本區塊來源:
[Day16] Vue 3 單元測試 (Unit Testing) – Vue Test Utils + Jest 基本介紹 & 安裝 – iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
其他測試可參考:
當然還有其他框架的測試方法,可以參考這頁:
其他 Jest 功能
Jest 雖然標榜免設定,但他還是可以視需要做調整,以符合 Node.js 專案的需求。
在設定之前,Jest 其實有提供初始化設定檔的指令,指令如下:
yarn jest --init
執行後他會問你一些問題
- 是否在
package.json
引入測試指令(例如:yarn test
) - 是否在設定檔使用 TypeScript
- 您的測試環境為何?(Node/Browser)
- 是否產生覆蓋率報告
<aside> 👉 如果選
Y
會問你要用哪個引擎</aside>
- 測試前是否清除 mock calls、instances、contexts 和 results <aside> 👉 我不太清楚這是清除啥,所以我選
N
</aside>
問完之後會產生一個檔案叫 jest.config.js

而如果您第一個問題回答 Y
則會在 package.json
新增這段

<aside> 👉 Config 建立完了,開始介紹一些功能
</aside>
Coverage 程式碼覆蓋報表
Jest 在測試時可以選擇產生覆蓋率報表,可幫助檢查程式碼的所有部分是否都有被測試到
開啟報表的方式有兩種:
- 執行時加上
--coverage
yarn jest --coverage
- 在設定檔中啟用,建立設定檔時可以選擇啟用或是透過以下選項手動啟用
jest.config.js
相關設定// 執行測試時產生報表 collectCoverage: true, // 包含在覆蓋率報表內的程式碼路徑,以字串陣列表示 collectCoverageFrom: [], // 產生的報表輸出檔路徑 coverageDirectory: "coverage", // 跳過覆蓋率偵測的路徑列表,以 regexp 陣列表示 coveragePathIgnorePatterns: [ "/node_modules/" ], // 指定覆蓋率提供程式 coverageProvider: "babel", // 覆蓋率報告的輸出格式 coverageReporters: [ "json", "text", "lcov", "clover" ], // 指定最小允許的覆蓋值,若低於這個值會導致程式回傳非 0 值(執行失敗) coverageThreshold: { global: { branches: 80, functions: 80, lines: 80, statements: -10, }, },
開啟之後執行測試會多出一個表格:

會列出所有檔案以及覆蓋率報告:
- Stmts – (Statements): 在測試中至少執行一次的指令
- Branch: if 的每個條件至少要執行一次
- Funcs: 每個含式至少要執行一次
- Lines: 測試中至少執行一次的行
另外也會列出沒有被涵蓋到的部分,以另一個專案為例,如下圖:

先前的 VSCode 插件 – Jest 也有提供覆蓋率報告
打開命令列( Ctrl + Shift + P
或 F1
),輸入 toggle coverage

即可切換覆蓋率報告,沒有被覆蓋到的程式碼會以紅底顯示,有時候需要用插件重新跑一次測試才會出現

Setup / Teardown
此功能可以指定開始測試前跟測試後需要執行的程式碼,主要分成幾個範圍:
- 寫在測試檔內
- beforeEach / afterEach
beforeEach(() => { // 放上你在每個測試開始前要執行的程式 }); afterEach(() => { // 放上你在每個測試結束後要執行的程式 });
指定在每個測試開始前 / 結束後要執行的程式碼,執行單位是一個測試 - beforeAll / afterAll
beforeAll(() => { // 放上範圍內所有測試開始前要執行的程式 }); afterAll(() => { // 放上範圍內所有測試結束後要執行的程式 });
指定在所在範圍內的所有測試開始前 / 結束後要執行的程式碼
test/scope.test.js
beforeAll(() => console.log("1 - beforeAll")); afterAll(() => console.log("1 - afterAll")); beforeEach(() => console.log("1 - beforeEach")); afterEach(() => console.log("1 - afterEach")); test("", () => console.log("1 - test1")); describe("Scoped / Nested block", () => { beforeAll(() => console.log("2 - beforeAll")); afterAll(() => console.log("2 - afterAll")); beforeEach(() => console.log("2 - beforeEach")); afterEach(() => console.log("2 - afterEach")); test("", () => console.log("2 - test1")); test("", () => console.log("2 - test2")); }); test("", () => console.log("1 - test2"));
- 輸出:
PASS test/scope.test.js ● Console console.log 1 - beforeAll at Object.log (test/scope.test.js:1:25) console.log 1 - beforeEach at Object.log (test/scope.test.js:3:26) console.log 1 - test at Object.log (test/scope.test.js:6:24) console.log 1 - afterEach at Object.log (test/scope.test.js:4:25) console.log 2 - beforeAll at Object.log (test/scope.test.js:9:27) console.log 1 - beforeEach at Object.log (test/scope.test.js:3:26) console.log 2 - beforeEach at Object.log (test/scope.test.js:11:28) console.log 2 - test at Object.log (test/scope.test.js:14:26) console.log 2 - afterEach at Object.log (test/scope.test.js:12:27) console.log 1 - afterEach at Object.log (test/scope.test.js:4:25) console.log 2 - afterAll at Object.log (test/scope.test.js:10:26) console.log 1 - afterAll at Object.log (test/scope.test.js:2:24)
- beforeEach / afterEach
- 寫在 setup file 此方法為將測試開始前 / 結束後執行的程式碼獨立寫成檔案,需要在
jest.config.js
中指定- setupFiles
// 每個測試環境建立前執行的程式,以路徑陣列指定 setupFiles: [],
<aside> 💡 因為此時測試環境還沒建立,因此包括beforeAll
等所有測試語法尚未被定義,所以沒辦法指定是什麼時候執行,只能放在測試的最前面執行 </aside> - setupFilesAfterEnv
// 每個測試環境建立後測試執行前執行的程式,以路徑陣列指定 setupFilesAfterEnv: [],
<aside> 💡 此時測試環境已經建立完成,因此可以用上述方法在每個測試檔案使用beforeAll
/afterAll
/beforeEach
/afterEach
,而且執行優先度最高 </aside>
test/scope.test.js
test/scope2.test.js
beforeAll(() => console.log("1.2 - beforeAll")); afterAll(() => console.log("1.2 - afterAll")); beforeEach(() => console.log("1.2 - beforeEach")); afterEach(() => console.log("1.2 - afterEach")); test("", () => console.log("1.2 - test1")); describe("Scoped / Nested block", () => { beforeAll(() => console.log("2.2 - beforeAll")); afterAll(() => console.log("2.2 - afterAll")); beforeEach(() => console.log("2.2 - beforeEach")); afterEach(() => console.log("2.2 - afterEach")); test("", () => console.log("2.2 - test1")); test("", () => console.log("2.2 - test2")); }); test("", () => console.log("1.2 - test2"));
test/setup.js
// 因為測試環境還沒建立 // 如果使用 beforeAll / afterAll / beforeEach / afterEach 會出現 undefined 錯誤 console.log("3 - setup");
test/setupAfterEnv.js
beforeAll(() => console.log("4 - beforeAll - setupAfterEnv")); afterAll(() => console.log("4 - afterAll - setupAfterEnv")); beforeEach(() => console.log("4 - beforeEach - setupAfterEnv")); afterEach(() => console.log("4 - afterEach - setupAfterEnv"));
jest.config.json
// The paths to modules that run some code to configure or set up the testing environment before each test setupFiles: ["./test/setup.js"], // A list of paths to modules that run some code to configure or set up the testing framework before each test setupFilesAfterEnv: ["./test/setupAfterEnv.js"],
- 輸出
PASS test/scope2.test.js ● Console console.log 3 - setup at Object.<anonymous> (test/setup.js:3:9) console.log 4 - beforeAll - setupAfterEnv at Object.log (test/setupAfterEnv.js:1:25) console.log 1.2 - beforeAll at Object.log (test/scope2.test.js:1:25) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1.2 - beforeEach at Object.log (test/scope2.test.js:3:26) console.log 1.2 - test1 at Object.log (test/scope2.test.js:6:24) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1.2 - afterEach at Object.log (test/scope2.test.js:4:25) console.log 2.2 - beforeAll at Object.log (test/scope2.test.js:9:27) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1.2 - beforeEach at Object.log (test/scope2.test.js:3:26) console.log 2.2 - beforeEach at Object.log (test/scope2.test.js:11:28) console.log 2.2 - test1 at Object.log (test/scope2.test.js:14:26) console.log 2.2 - afterEach at Object.log (test/scope2.test.js:12:27) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1.2 - afterEach at Object.log (test/scope2.test.js:4:25) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1.2 - beforeEach at Object.log (test/scope2.test.js:3:26) console.log 2.2 - beforeEach at Object.log (test/scope2.test.js:11:28) console.log 2.2 - test2 at Object.log (test/scope2.test.js:15:26) console.log 2.2 - afterEach at Object.log (test/scope2.test.js:12:27) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1.2 - afterEach at Object.log (test/scope2.test.js:4:25) console.log 2.2 - afterAll at Object.log (test/scope2.test.js:10:26) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1.2 - beforeEach at Object.log (test/scope2.test.js:3:26) console.log 1.2 - test2 at Object.log (test/scope2.test.js:18:24) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1.2 - afterEach at Object.log (test/scope2.test.js:4:25) console.log 4 - afterAll - setupAfterEnv at Object.log (test/setupAfterEnv.js:2:24) console.log 1.2 - afterAll at Object.log (test/scope2.test.js:2:24) PASS test/scope.test.js ● Console console.log 3 - setup at Object.<anonymous> (test/setup.js:3:9) console.log 4 - beforeAll - setupAfterEnv at Object.log (test/setupAfterEnv.js:1:25) console.log 1 - beforeAll at Object.log (test/scope.test.js:1:25) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1 - beforeEach at Object.log (test/scope.test.js:3:26) console.log 1 - test1 at Object.log (test/scope.test.js:6:24) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1 - afterEach at Object.log (test/scope.test.js:4:25) console.log 2 - beforeAll at Object.log (test/scope.test.js:9:27) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1 - beforeEach at Object.log (test/scope.test.js:3:26) console.log 2 - beforeEach at Object.log (test/scope.test.js:11:28) console.log 2 - test1 at Object.log (test/scope.test.js:14:26) console.log 2 - afterEach at Object.log (test/scope.test.js:12:27) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1 - afterEach at Object.log (test/scope.test.js:4:25) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1 - beforeEach at Object.log (test/scope.test.js:3:26) console.log 2 - beforeEach at Object.log (test/scope.test.js:11:28) console.log 2 - test2 at Object.log (test/scope.test.js:15:26) console.log 2 - afterEach at Object.log (test/scope.test.js:12:27) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1 - afterEach at Object.log (test/scope.test.js:4:25) console.log 2 - afterAll at Object.log (test/scope.test.js:10:26) console.log 4 - beforeEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:3:26) console.log 1 - beforeEach at Object.log (test/scope.test.js:3:26) console.log 1 - test2 at Object.log (test/scope.test.js:18:24) console.log 4 - afterEach - setupAfterEnv at Object.log (test/setupAfterEnv.js:4:25) console.log 1 - afterEach at Object.log (test/scope.test.js:4:25) console.log 4 - afterAll - setupAfterEnv at Object.log (test/setupAfterEnv.js:2:24) console.log 1 - afterAll at Object.log (test/scope.test.js:2:24)
- setupFiles
- global setup / teardown 而這個方法又是更外層的,是整個測試工作開始前和整個測試工作結束後才會執行一次測試的程式碼片段,需要在
jest.config.js
中指定,且程式碼需透過 module 的方式 export 出來jest.config.js
// 在所有測試單元開始前執行的程式模組 globalSetup: '', // 在所有測試單元結束後執行的程式模組 globalTeardown: '',
- 被引用的檔案(以 ES6 語法為例)
export default () => { // 放上要執行的程式片段 }
最後,整合上述範例,完整的測試執行順序,如以下範例:
test/scope.test.js
test/scope2.test.js
test/setup.js
test/setupAfterEnv.js
test/bootstrap.js
export default () => { console.log("5 - bootstrap"); }
test/teardown.js
export default () => { console.log("5 - teardown"); }
jest.config.js
- 上個變更
- 新增變更
// A path to a module which exports an async function that is triggered once before all test suites globalSetup: "./test/bootstrap.js", // A path to a module which exports an async function that is triggered once after all test suites globalTeardown: "./test/teardown.js",
- 輸出
yarn run v1.22.19 $ jest Determining test suites to run...5 - bootstrap <---- Here
- 中間部分和前一個一樣
Test Suites: 3 passed, 3 total Tests: 10 passed, 10 total Snapshots: 0 total Time: 2.045 s Ran all test suites. 5 - teardown <---------------------------------------- Here Done in 4.11s.