성능 향상
테스트 격리
기본적으로 Vitest는 pool 설정을 기반으로 모든 테스트 파일을 격리된 환경에서 실행합니다.
threads
풀은 각 테스트 파일을 별도의Worker
에서 실행합니다.forks
풀은 각 테스트 파일을 별도의 forked child process에서 실행합니다.vmThreads
풀은 각 테스트 파일을 별도의 VM context에서 실행하며, 병렬 처리를 위해 워커를 활용합니다.
이러한 격리 방식은 테스트 실행 시간을 상당히 증가시킬 수 있습니다. 특히 부작용에 의존하지 않고 상태를 깔끔하게 정리하는 프로젝트(대부분 node
환경의 프로젝트가 이에 해당)의 경우, 이러한 시간 증가는 바람직하지 않을 수 있습니다. 이럴 때는 격리 기능을 비활성화하여 테스트 속도를 개선할 수 있습니다. 격리를 끄려면 CLI에 --no-isolate
플래그를 추가하거나, 설정 파일에서 test.isolate
속성을 false
로 설정하면 됩니다. poolMatchGlobs
를 사용하여 여러 풀을 동시에 사용하는 경우, 특정 풀에 대해서만 격리를 비활성화하는 것도 가능합니다.
vitest --no-isolate
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
isolate: false,
// 특정 풀에 대해서만 격리를 비활성화할 수도 있습니다.
poolOptions: {
forks: {
isolate: false,
},
},
},
});
TIP
vmThreads
풀을 사용하는 경우 격리를 비활성화할 수 없습니다. 테스트 성능을 향상시키려면 대신 threads
풀을 사용하세요.
일부 프로젝트에서는 시작 시간을 개선하기 위해 파일 병렬 처리를 비활성화하는 것이 유리할 수 있습니다. 이를 위해 CLI에 --no-file-parallelism
플래그를 제공하거나, 구성에서 test.fileParallelism
속성을 false
로 설정합니다.
vitest --no-file-parallelism
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
fileParallelism: false,
},
});
풀
Vitest는 기본적으로 pool: 'forks'
설정으로 테스트를 실행합니다. 'forks'
풀은 호환성 문제(작업자 종료 실패 및 세그멘테이션 오류)에 더 강점이 있지만, 대규모 프로젝트에서는 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 # 1번째 머신
vitest run --reporter=blob --shard=2/3 # 2번째 머신
vitest run --reporter=blob --shard=3/3 # 3번째 머신
각 장비의 .vitest-reports
폴더에 저장된 결과를 모아서 --merge-reports
옵션으로 병합합니다.
vitest --merge-reports
Github 액션 예시
이 설정은 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@v4
- 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@v4
- 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
# 풀에 따라 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 --merge-reports