提升效能
測試隔離
預設情況下,Vitest 會根據其所選的 pool 在隔離的環境中執行每個測試檔案:
threads
pool 會在單獨的Worker
中執行每個測試檔案。forks
pool 會在單獨的 forked child process 中執行每個測試檔案。vmThreads
pool 會在單獨的 VM context 中執行每個測試檔案,但它使用 worker 進行平行處理。
這種隔離機制可能會顯著增加測試執行時間。對於不依賴副作用且能正確清理其狀態的專案(通常適用於 node
環境的專案)而言,這可能並非理想情況。在這種情況下,停用隔離功能可提升測試速度。您可以透過在 CLI 中提供 --no-isolate
參數,或將設定檔中的 test.isolate
屬性設為 false
來實現。
vitest --no-isolate
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
isolate: false,
// 您也可以僅針對特定 pool 停用隔離
poolOptions: {
forks: {
isolate: false,
},
},
},
});
TIP
若您使用 vmThreads
pool,則無法停用隔離功能。請改用 threads
pool 以提升測試效能。
對於某些專案而言,停用檔案層級的平行處理以縮短啟動時間可能也是理想的選擇。為此,請在 CLI 中提供 --no-file-parallelism
參數,或將設定檔中的 test.fileParallelism
屬性設為 false
。
vitest --no-file-parallelism
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
fileParallelism: false,
},
});
Pool 選項
預設情況下,Vitest 會在 pool: 'forks'
中執行測試。儘管 'forks'
pool 在處理相容性問題(例如:掛起程序和 segfaults)方面表現較佳,但在大型專案中,其速度可能略慢於 pool: 'threads'
。
您可以嘗試透過切換設定檔中的 pool
選項來改善測試執行時間:
vitest --pool=threads
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
pool: 'threads',
},
});
分片
測試分片是將測試套件劃分為多個組或分片的過程。當您擁有大型測試套件且有多台機器可同時執行該套件的子集時,這將會非常有用。
若要將 Vitest 測試分割成多個不同的執行,請搭配使用 --shard
選項與 --reporter=blob
選項:
vitest run --reporter=blob --shard=1/3 # 第一台機器
vitest run --reporter=blob --shard=2/3 # 第二台機器
vitest run --reporter=blob --shard=3/3 # 第三台機器
Vitest 會將您的測試檔案(而非測試案例)分割成碎片。如果您有 1000 個測試檔案,
--shard=1/4
選項將執行 250 個測試檔案,無論個別檔案包含多少測試案例。
從每台機器收集儲存在 .vitest-reports
目錄中的結果,並使用 --merge-reports
選項將其合併:
vitest run --merge-reports
Github action example
此設定也應用於 https://github.com/vitest-tests/test-sharding。
# 參考自 https://playwright.dev/docs/test-sharding
name: Tests
on:
push:
branches:
- main
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
- name: Install dependencies
run: pnpm i
- name: Run tests
run: pnpm run test --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
- name: Upload blob report to GitHub Actions Artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: blob-report-${{ matrix.shardIndex }}
path: .vitest-reports/*
include-hidden-files: true
retention-days: 1
merge-reports:
if: ${{ !cancelled() }}
needs: [tests]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install pnpm
uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0
- name: Install dependencies
run: pnpm i
- name: Download blob reports from GitHub Actions Artifacts
uses: actions/download-artifact@v4
with:
path: .vitest-reports
pattern: blob-report-*
merge-multiple: true
- name: Merge reports
run: npx vitest --merge-reports
TIP
測試分片在多核心 CPU 的機器上同樣能發揮效用。
Vitest 僅會在主執行緒中執行單一 Vite 伺服器。其餘執行緒則用於執行測試檔案。 在高 CPU 數量的機器中,主執行緒可能成為效能瓶頸,因為它無法處理來自其他執行緒的所有請求。例如,在 32 CPU 的機器中,主執行緒需處理來自 31 個測試執行緒的負載。
為減輕主執行緒 Vite 伺服器的負載,您可以使用測試分片。負載可在多個 Vite 伺服器之間平衡。
# 將 32 CPU 上的測試分割成 4 個分片的範例。
# 由於每個程序需要 1 個主執行緒,因此有 7 個執行緒用於測試執行器 (1+7)*4 = 32
# 根據 pool 使用 VITEST_MAX_THREADS 或 VITEST_MAX_FORKS:
VITEST_MAX_THREADS=7 vitest run --reporter=blob --shard=1/4 & \
VITEST_MAX_THREADS=7 vitest run --reporter=blob --shard=2/4 & \
VITEST_MAX_THREADS=7 vitest run --reporter=blob --shard=3/4 & \
VITEST_MAX_THREADS=7 vitest run --reporter=blob --shard=4/4 & \
wait # https://man7.org/linux/man-pages/man2/waitpid.2.html
vitest run --merge-reports