遷移指南
從 Vitest 0.34.6 遷移
最低需求
Vitest 1.0 需要 Vite 5.0 和 Node.js 18 或更高版本。
所有 @vitest/*
子套件都需要 Vitest 版本 1.0。
快照更新 #3961
快照中的引號不再轉譯,且所有快照都使用反引號 (`),即使字串只有一行。
- 引號不再轉譯
expect({ foo: 'bar' }).toMatchInlineSnapshot(`
Object {
- \\"foo\\": \\"bar\\",
+ "foo": "bar",
}
`)
- 單行快照現在使用 "`" 引號,而不是 '
- expect('some string').toMatchInlineSnapshot('"some string"')
+ expect('some string').toMatchInlineSnapshot(`"some string"`)
@vitest/snapshot
套件也有 變更。如果您沒有直接使用它,則不需要變更任何內容。
- 您不再需要延伸
SnapshotClient
只為覆寫equalityCheck
方法:只要在初始化實例時將其傳遞為isEqual
即可 client.setTest
已重新命名為client.startCurrentRun
client.resetCurrent
已重新命名為client.finishCurrentRun
池已標準化 #4172
我們移除了許多組態選項,以簡化根據您的需求組態執行器的過程。如果您依賴 --threads
或其他相關旗標,請查看遷移範例。
--threads
現在是--pool=threads
--no-threads
現在是--pool=forks
--single-thread
現在是--poolOptions.threads.singleThread
--experimental-vm-threads
現在是--pool=vmThreads
--experimental-vm-worker-memory-limit
現在是--poolOptions.vmThreads.memoryLimit
--isolate
現在是--poolOptions.<pool-name>.isolate
和browser.isolate
test.maxThreads
現在是test.poolOptions.<pool-name>.maxThreads
test.minThreads
現在是test.poolOptions.<pool-name>.minThreads
test.useAtomics
現在是test.poolOptions.<pool-name>.useAtomics
test.poolMatchGlobs.child_process
現在是test.poolMatchGlobs.forks
test.poolMatchGlobs.experimentalVmThreads
現在是test.poolMatchGlobs.vmThreads
{
scripts: {
- "test": "vitest --no-threads"
// For identical behaviour:
+ "test": "vitest --pool forks --poolOptions.forks.singleFork"
// Or multi parallel forks:
+ "test": "vitest --pool forks"
}
}
{
scripts: {
- "test": "vitest --experimental-vm-threads"
+ "test": "vitest --pool vmThreads"
}
}
{
scripts: {
- "test": "vitest --isolate false"
+ "test": "vitest --poolOptions.threads.isolate false"
}
}
{
scripts: {
- "test": "vitest --no-threads --isolate false"
+ "test": "vitest --pool forks --poolOptions.forks.isolate false"
}
}
涵蓋範圍變更 #4265, #4442
選項 coverage.all
現在預設啟用。這表示所有符合 coverage.include
樣式的專案檔案都將被處理,即使它們未執行。
涵蓋範圍閾值的 API 形狀已變更,現在支援使用全域樣式為特定檔案指定閾值
export default defineConfig({
test: {
coverage: {
- perFile: true,
- thresholdAutoUpdate: true,
- 100: true,
- lines: 100,
- functions: 100,
- branches: 100,
- statements: 100,
+ thresholds: {
+ perFile: true,
+ autoUpdate: true,
+ 100: true,
+ lines: 100,
+ functions: 100,
+ branches: 100,
+ statements: 100,
+ }
}
}
})
模擬類型 #4400
已移除一些類型,改用 Jest 風格的「模擬」命名。
- import { EnhancedSpy, SpyInstance } from 'vitest'
+ import { MockInstance } from 'vitest'
警告
SpyInstance
已過時,改用 MockInstance
,並將在下一個主要版本中移除。
計時器模擬 #3925
vi.useFakeTimers()
不再自動模擬 process.nextTick
。仍可透過明確指定 vi.useFakeTimers({ toFake: ['nextTick'] })
來模擬 process.nextTick
。
不過,在使用 --pool=forks
時無法模擬 process.nextTick
。如果您需要模擬 process.nextTick
,請使用其他 --pool
選項。
從 Jest 遷移
Vitest 採用與 Jest 相容的 API 設計,目的是讓從 Jest 移轉的過程盡可能簡單。儘管如此,您仍可能會遇到以下差異
預設為全域變數
Jest 預設啟用 全域變數 API。Vitest 則沒有。您可以透過 globals
設定 啟用全域變數,或更新程式碼以使用從 vitest
模組匯入的內容。
如果您決定停用全域變數,請注意像 testing-library
等常見函式庫將不會執行自動 DOM 清理。
模擬模組
在 Jest 中模擬模組時,工廠參數的回傳值是預設匯出。在 Vitest 中,工廠參數必須回傳一個物件,其中每個匯出都明確定義。例如,以下 jest.mock
必須更新如下
jest.mock('./some-path', () => 'hello')
vi.mock('./some-path', () => ({
default: 'hello',
}))
如需更多詳細資訊,請參閱 vi.mock
API 區段。
自動模擬行為
與 Jest 不同的是,<root>/__mocks__
中的模擬模組不會載入,除非呼叫 vi.mock()
。如果您需要在每個測試中模擬它們,就像在 Jest 中一樣,您可以在 setupFiles
中模擬它們。
匯入模擬套件的原始檔
如果您只部分模擬套件,您可能之前使用過 Jest 的函式 requireActual
。在 Vitest 中,您應該用 vi.importActual
取代這些呼叫。
const { cloneDeep } = jest.requireActual('lodash/cloneDeep')
const { cloneDeep } = await vi.importActual('lodash/cloneDeep')
將模擬擴充至外部函式庫
Jest 預設會執行此動作,當模擬模組並希望將此模擬擴充至使用相同模組的其他外部函式庫時,您應該明確指出要模擬哪個第三方函式庫,以便外部函式庫透過使用 server.deps.inline 成為您的原始程式碼的一部分。
server.deps.inline: ["lib-name"]
存取模擬 Promise 的回傳值
Jest 和 Vitest 都會將所有模擬呼叫的結果儲存在 mock.results
陣列中,其中每個呼叫的回傳值儲存在 value
屬性中。然而,當模擬或監控 Promise(例如使用 mockResolvedValue
)時,在 Jest 中 value
屬性會是一個 Promise,而在 Vitest 中,當 Promise 解析時,它會變成已解析的值。
await expect(spy.mock.results[0].value).resolves.toBe(123)
expect(spy.mock.results[0].value).toBe(123)
環境變數
如同 Jest,如果 Vitest 之前未設定,則會將 NODE_ENV
設為 test
。Vitest 也有 JEST_WORKER_ID
的對應項,稱為 VITEST_POOL_ID
(始終小於或等於 maxThreads
),因此如果您依賴它,請不要忘記重新命名它。Vitest 也公開了 VITEST_WORKER_ID
,它是正在執行的工作程序的唯一 ID - 這個數字不受 maxThreads
影響,並且會隨著每個建立的工作程序而增加。
取代屬性
如果您想要修改物件,您將在 Jest 中使用 replaceProperty API,您可以在 Vitest 中使用 vi.stubEnv
或 vi.spyOn
來執行相同的操作。
完成回呼
從 Vitest v0.10.0 開始,宣告測試的回呼樣式已棄用。您可以將它們改寫為使用 async
/await
函式,或使用 Promise 模擬回呼樣式。
it('should work', (done) => {
it('should work', () => new Promise(done => {
// ...
done()
})
}))
掛鉤
beforeAll
/beforeEach
掛鉤可能會在 Vitest 中傳回 中斷函式。因此,如果您傳回 undefined
或 null
以外的內容,您可能需要改寫掛鉤宣告。
beforeEach(() => setActivePinia(createTestingPinia()))
beforeEach(() => { setActivePinia(createTestingPinia()) })
在 Jest 中,掛鉤會依序呼叫(一個接著一個)。預設情況下,Vitest 會並行執行掛鉤。若要使用 Jest 的行為,請更新 sequence.hooks
選項
export default defineConfig({
test: {
sequence: {
hooks: 'list',
}
}
})
類型
Vitest 沒有等同於 jest
名稱空間,因此您需要直接從 vitest
匯入類型
let fn: jest.Mock<string, [string]>
import type { Mock } from 'vitest'
let fn: Mock<[string], string>
此外,Vitest 的第一個參數為 Args
類型,而不是 Returns
,如您在 diff 中所見。
計時器
Vitest 不支援 Jest 的舊版計時器。
逾時
如果您使用 jest.setTimeout
,您需要移轉到 vi.setConfig
jest.setTimeout(5_000)
vi.setConfig({ testTimeout: 5_000 })
Vue 擷取快照
這不是 Jest 特有的功能,但如果你之前使用 Jest 與 vue-cli 預設值,你將需要安裝 jest-serializer-vue
套件,並在 setupFiles 中使用它
vite.config.js
import { } from 'vite'
export default ({
: {
: ['./tests/unit/setup.js']
}
})
tests/unit/setup.js
import vueSnapshotSerializer from 'jest-serializer-vue'
expect.addSnapshotSerializer(vueSnapshotSerializer)
否則你的快照將會有許多跳脫的 "
字元。