troubleshooting2025-02-16·9 min·197/348

Vitest 테스트 설정 에러: 테스트 환경 구성 및 문제 해결

Vitest 테스트 설정 시 발생하는 에러와 해결 방법, 그리고 최적화 기법을 설명합니다.

Vitest 테스트 설정 에러

Introduction

Vitest는 Vite 기반의 빠르고 현대적인 테스트 프레임워크입니다. Jest와 호환되는 API를 제공하면서도 Vite의 빠른 핫 리로딩과 ESM 지원을 활용할 수 있습니다. 하지만 설정 과정에서 여러 가지 에러에 직면할 수 있습니다. 이 글에서는 Vitest 설정 에러 해결 방법을 다루겠습니다.

Environment

// package.json
{
  "name": "my-project",
  "scripts": {
    "test": "vitest",
    "test:coverage": "vitest run --coverage",
    "test:ui": "vitest --ui"
  },
  "devDependencies": {
    "vitest": "^1.2.0",
    "@vitest/ui": "^1.2.0",
    "@vitest/coverage-v8": "^1.2.0",
    "jsdom": "^24.0.0"
  }
}
npx vitest --version
# Vitest 1.2.1

Problem

Vitest 설정 시 발생하는 에러들:

// vitest.config.ts
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/test/setup.ts'
  }
});

// 에러: Cannot find module 'jsdom'
// ERROR: Missing jsdom package
# 실행 시 에러
npx vitest run

# 에러 메시지:
# Error: Cannot find package 'jsdom'
# at node_modules/.pnpm/vitest@1.2.1/node_modules/vitest/dist/config.js:123
// 환경 설정 충돌
export default defineConfig({
  test: {
    environment: 'jsdom',
    // jsdom 설정이 필요한 경우
    environmentOptions: {
      jsdom: {
        url: 'http://localhost'
      }
    }
  }
});

// 에러: Environment 'jsdom' not found
// vitest.config.ts 파일의 환경 설정이 올바르지 않음

Analysis

Vitest 설정 에러의 원인을 분석했습니다:

# 의존성 확인
cat package.json | grep -E "(vitest|jsdom)"

# node_modules 확인
ls node_modules | grep -E "(vitest|jsdom)"

# Vitest 설정 파일 검색
find . -name "vitest.config.*" -type f
# ./vitest.config.ts

# Vite 설정과 충돌 확인
ls -la vite.config.*
# ./vite.config.ts
// Vite 설정과 Vitest 설정 충돌
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': '/src'
    }
  }
});

// vitest.config.ts에서 Vite 설정을 다시 정의해야 하는 문제

Solution

1단계: 올바른 패키지 설치

# Vitest 및 관련 패키지 설치
npm install --save-dev vitest @vitest/ui @vitest/coverage-v8 jsdom

# 또는 pnpm 사용 시
pnpm add -D vitest @vitest/ui @vitest/coverage-v8 jsdom
// package.json에 스크립트 추가
{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "test:coverage": "vitest run --coverage",
    "test:ui": "vitest --ui",
    "test:watch": "vitest --watch"
  }
}

2단계: Vitest 설정 파일 구성

// vitest.config.ts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/test/setup.ts',
    include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
    exclude: ['node_modules', 'dist', '.idea', '.git'],
    environmentOptions: {
      jsdom: {
        url: 'http://localhost:3000',
        pretendToBeVisual: true
      }
    },
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      exclude: [
        'node_modules/',
        'src/test/',
        '**/*.d.ts',
        '**/*.config.*',
        '**/index.ts'
      ]
    }
  },
  resolve: {
    alias: {
      '@': '/src'
    }
  }
});

3단계: setup 파일 작성

// src/test/setup.ts
import '@testing-library/jest-dom';
import { cleanup } from '@testing-library/react';
import { afterEach, vi } from 'vitest';

// 각 테스트 후 정리
afterEach(() => {
  cleanup();
});

// 전역 모의(mock) 설정
vi.mock('next/navigation', () => ({
  useRouter: () => ({
    push: vi.fn(),
    back: vi.fn(),
    forward: vi.fn()
  }),
  usePathname: () => '/'
}));

// 환경 변수 설정
Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: vi.fn().mockImplementation(query => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: vi.fn(),
    removeListener: vi.fn(),
    addEventListener: vi.fn(),
    removeEventListener: vi.fn(),
    dispatchEvent: vi.fn()
  }))
});

4단계: Vite 설정 통합

// vite.config.ts (통합 설정)
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  },
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/test/setup.ts',
    include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}']
  }
});

// vitest.config.ts는 vite.config.ts를 상속받으므로
// 추가 설정만 별도로 정의 가능

Lessons Learned

  1. 의존성 관리: jsdom과 같은 환경 패키지는 반드시 devDependencies에 포함해야 합니다
  2. 설정 충돌 회피: Vite 설정과 Vitest 설정이 충돌하지 않도록 주의해야 합니다
  3. setup 파일 활용: 전역 테스트 설정은 setup 파일에서 수행하면 테스트 코드 중복을 줄일 수 있습니다
  4. 커버리지 설정: 커버리지 제외 파일을 명시하여 불필요한 파일이 포함되지 않도록 해야 합니다
  5. IDE 통합: VSCode 확장프로그램을 사용하면 Vitest 테스트를 IDE에서 직접 실행할 수 있습니다

이 블로그는 외부 스폰서십, 제휴 마케팅 또는 광고 수익을 받지 않습니다.