테스트 성능 프로파일링
Vitest를 실행하면 테스트에 대한 다양한 시간 측정 항목이 보고됩니다.
bashRUN v2.1.1 /x/vitest/examples/profiling ✓ test/prime-number.test.ts (1) 4517ms ✓ generate prime number 4517ms Test Files 1 passed (1) Tests 1 passed (1) Start at 09:32:53 Duration 4.80s (transform 44ms, setup 0ms, collect 35ms, tests 4.52s, environment 0ms, prepare 81ms) # Time metrics ^^
- Transform: 파일 변환에 소요된 시간입니다. 파일 변환 섹션을 참조하세요.
- Setup:
setupFiles
파일을 실행하는 데 소요된 시간입니다. - Collect: 테스트 파일의 모든 테스트를 수집하는 데 소요된 시간입니다. 여기에는 모든 파일 의존성을 가져오는 데 소요된 시간이 포함됩니다.
- Tests: 실제 테스트 케이스를 실행하는 데 걸린 시간입니다.
- Environment: 예를 들어 JSDOM과 같은 테스트
environment
를 설정하는 데 소요된 시간입니다. - Prepare: Vitest가 테스트 러너를 준비하는 데 걸린 시간입니다.
테스트 러너
테스트 실행 시간이 길다면, 테스트 러너의 프로필을 생성할 수 있습니다. 다음 옵션에 대한 자세한 내용은 NodeJS 문서를 참조하세요.
WARNING
--prof
옵션은 node:worker_threads
제한으로 인해 pool: 'threads'
와 함께 작동하지 않습니다.
이러한 옵션을 Vitest의 테스트 러너에 전달하려면 Vitest 구성에서 poolOptions.<pool>.execArgv
를 정의해야 합니다.
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
pool: 'forks',
poolOptions: {
forks: {
execArgv: [
'--cpu-prof',
'--cpu-prof-dir=test-runner-profile',
'--heap-prof',
'--heap-prof-dir=test-runner-profile',
],
// 단일 프로필을 생성하려면
singleFork: true,
},
},
},
});
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
pool: 'threads',
poolOptions: {
threads: {
execArgv: [
'--cpu-prof',
'--cpu-prof-dir=test-runner-profile',
'--heap-prof',
'--heap-prof-dir=test-runner-profile',
],
// 단일 프로필을 생성하려면
singleThread: true,
},
},
},
});
테스트 실행 후에는 test-runner-profile/*.cpuprofile
및 test-runner-profile/*.heapprofile
파일이 생성됩니다. 이 파일을 분석하는 방법에 대한 지침은 프로파일링 기록 검사 섹션을 참조하세요.
예시는 프로파일링 | 예시를 참조하세요.
메인 스레드
메인 스레드 프로파일링은 Vitest의 Vite 사용 방식과 globalSetup
파일을 디버깅하는 데 유용합니다. 또한, Vite 플러그인이 이 스레드에서 실행됩니다.
이를 위해서는 Vitest를 실행하는 Node 프로세스에 인수를 전달해야 합니다.
$ node --cpu-prof --cpu-prof-dir=main-profile ./node_modules/vitest/vitest.mjs --run
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^
# NodeJS 인수 Vitest 인수
테스트가 실행된 후 main-profile/*.cpuprofile
파일이 생성되어야 합니다. 이 파일을 분석하는 방법에 대한 지침은 프로파일링 기록 검사 섹션을 참조하세요.
파일 변환
테스트 변환 및 수집 시간이 길다면, DEBUG=vite-node:*
환경 변수를 사용하여 vite-node
에 의해 어떤 파일이 변환되고 실행되는지 확인할 수 있습니다.
$ DEBUG=vite-node:* vitest --run
RUN v2.1.1 /x/vitest/examples/profiling
vite-node:server:request /x/vitest/examples/profiling/global-setup.ts +0ms
vite-node:client:execute /x/vitest/examples/profiling/global-setup.ts +0ms
vite-node:server:request /x/vitest/examples/profiling/test/prime-number.test.ts +45ms
vite-node:client:execute /x/vitest/examples/profiling/test/prime-number.test.ts +26ms
vite-node:server:request /src/prime-number.ts +9ms
vite-node:client:execute /x/vitest/examples/profiling/src/prime-number.ts +9ms
vite-node:server:request /src/unnecessary-file.ts +6ms
vite-node:client:execute /x/vitest/examples/profiling/src/unnecessary-file.ts +4ms
...
이 프로파일링 방법은 배럴 파일로 인한 불필요한 변환을 찾는 데 효과적입니다. 이 로그에 테스트 실행 시 불필요하게 로드된 파일이 있다면, 불필요하게 파일을 가져오는 배럴 파일이 원인일 수 있습니다.
Vitest UI를 사용하여 배럴 파일로 인한 느려짐을 디버깅할 수도 있습니다. 아래 예제는 배럴 파일을 사용하지 않고 직접 파일을 임포트하면 변환되는 파일 수를 약 85% 줄일 수 있음을 보여줍니다.
├── src
│ └── utils
│ ├── currency.ts
│ ├── formatters.ts <-- 테스트할 파일
│ ├── index.ts
│ ├── location.ts
│ ├── math.ts
│ ├── time.ts
│ └── users.ts
├── test
│ └── formatters.test.ts
└── vitest.config.ts
import { expect, test } from 'vitest';
import { formatter } from '../src/utils';
import { formatter } from '../src/utils/formatters';
test('formatter works', () => {
expect(formatter).not.toThrow();
});

파일이 어떻게 변환되는지 확인하려면 VITE_NODE_DEBUG_DUMP
환경 변수를 사용하여 변환된 파일을 파일 시스템에 기록할 수 있습니다.
$ VITE_NODE_DEBUG_DUMP=true vitest --run
[vite-node] [debug] dump modules to /x/examples/profiling/.vite-node/dump
RUN v2.1.1 /x/vitest/examples/profiling
...
$ ls .vite-node/dump/
_x_examples_profiling_global-setup_ts-1292904907.js
_x_examples_profiling_test_prime-number_test_ts-1413378098.js
_src_prime-number_ts-525172412.js
코드 커버리지
코드 커버리지 생성 속도가 느린 경우 DEBUG=vitest:coverage
환경 변수를 사용하여 성능 로깅을 활성화할 수 있습니다.
$ DEBUG=vitest:coverage vitest --run --coverage
RUN v3.1.1 /x/vitest-example
vitest:coverage Reading coverage results 2/2
vitest:coverage Converting 1/2
vitest:coverage 4 ms /x/src/multiply.ts
vitest:coverage Converting 2/2
vitest:coverage 552 ms /x/src/add.ts
vitest:coverage Uncovered files 1/2
vitest:coverage File "/x/src/large-file.ts" is taking longer than 3s
vitest:coverage 3027 ms /x/src/large-file.ts
vitest:coverage Uncovered files 2/2
vitest:coverage 4 ms /x/src/untested-file.ts
vitest:coverage Generate coverage total time 3521 ms
이 프로파일링 접근 방식은 커버리지 도구가 실수로 포함시킨 대용량 파일을 찾는 데 유용합니다. 예를 들어 설정에서 실수로 빌드된 대용량 minified JavaScript 파일을 커버리지에 포함시킨 경우 로그에서 확인할 수 있습니다. 이런 경우에는 coverage.include
및 coverage.exclude
옵션을 조정해야 할 수 있습니다.
프로파일링 기록 검사
다양한 도구를 사용하여 *.cpuprofile
및 *.heapprofile
파일의 내용을 검사할 수 있습니다. 예시는 아래 목록을 참조하십시오.