[트러블 슈팅] vitest storybook msw 환경 설정 오류 - 100-hours-a-week/4-bull4zo-fe GitHub Wiki

테스트 환경 설정 에러(5/28)

🐞 에러 내용

  • 단위 테스트를 vitest, 통합 테스트를 storybook의 play와 msw로 진행하려는 과정에서 pnpm test 시 storybook에서 msw실행이 되지 않는 오류 발생

🔍 원인 분석

  • pnpm test는 CLI에서 테스트를 진행하는데, storybook의 msw가 동작하기 위해서는 브라우저에서 동작할 필요성이 존재한다. 그런데 msw를 브라우저가 아닌 CLI에서 동작하려고 하면서 브라우저가 아니기 때문에 동작할 수 없다는 오류가 지속적으로 검출됨

✅ 해결 방법

  • .test 파일의 경우 CLI에서 검사하고, .stories 파일의 경우 브라우저 storybook에서 검사하도록 로직 분리 및 문제가 있던 세팅값 제거
// vitest.workspace.ts
import { storybookTest } from '@storybook/experimental-addon-test/vitest-plugin'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { defineWorkspace } from 'vitest/config'

const dirname =
  typeof __dirname !== 'undefined' ? __dirname : path.dirname(fileURLToPath(import.meta.url))

// More info at: https://storybook.js.org/docs/writing-tests/test-addon
export default defineWorkspace([
  {
    extends: 'vite.config.ts',
    test: {
      name: 'app',
      globals: true,
      environment: 'jsdom',
      include: ['src/**/*.{test,spec}.{js,ts,jsx,tsx}'],
      setupFiles: ['.storybook/vitest.setup.ts'],
    },
  },
  {
    extends: 'vite.config.ts',
    plugins: [
      storybookTest({
        configDir: path.join(dirname, '.storybook'),
      }),
    ],
    test: {
      name: 'storybook',
      globals: true,
      environment: 'jsdom',
      browser: {
        enabled: true,
        headless: true,
        provider: 'playwright',
        instances: [{ browser: 'chromium' }],
      },
      setupFiles: ['.storybook/vitest.setup.ts'],
    },
    optimizeDeps: {
      exclude: ['msw/node'],
    },
  },
])
  • vitest.worksapce에서 일반 CLI와 storybook 설정 분리 및 CLI의 경우 storybook 제외 설정
// .storybook/vitest.setup.ts
import { setProjectAnnotations } from '@storybook/react'
import '@testing-library/jest-dom'
import { beforeAll } from 'vitest'
import * as projectAnnotations from './preview'

// This is an important step to apply the right configuration when testing your stories.
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
const project = setProjectAnnotations([projectAnnotations])

beforeAll(project.beforeAll)
  • 이전 파일에서는 setup파일에서 msw의 server를 불러와서 실행하려고 시도했지만, 현재 setup은 storybook 기반 설정이기 때문에 node로 도작하는 과정에서 오류 발생. 추후 단위테스트에서도 msw가 필요하다면 setup파일을 추가하고, vitest기반 설정을 추가한 뒤, msw의 server를 호출해야함
// .storybook/preview.ts
import { type Preview } from '@storybook/react'
import { initialize, mswDecorator, mswLoader } from 'msw-storybook-addon'
import { handlers } from '../src/mocks/handlers'
import '../src/styles/globals.css'

initialize()

const preview: Preview = {
  parameters: {
    controls: {
      matchers: {
        color: /(background|color)$/i,
        date: /Date$/i,
      },
    },
    msw: {
      handlers,
    },
  },
  decorators: [mswDecorator],
  loaders: [mswLoader],
}

export default preview

  • storybook의 msw 설정 위치로, msw의 전체 핸들러를 추가하고, 로더와 데코레이터로 호출 및 전달을 열어줘야 preview아래서 만들어질 storybook에서 msw호출이 가능하다.

🤔 향후 대응 방안

  • 현재 단위 + 통합 테스트만 진행하고 있으며, e2e테스트는 설정은 되어 있지만 구체적으로 구상되어 있지는 않다. 현재는 e2e테스트는 playwright기반으로 동작할 예정이며, 추후 사용자 시나리오를 바탕으로 추가될 예정이다.
  • msw를 단위테스트에도 추가해야한다면 스토리북에 의존적인 setup파일을 새로 만들어서 vitest기반으로 수정해야한다.

💬 회고

  • 처음으로 단위, 통합, e2e 테스트 설정을 진행하면서 충돌이 많았지만, 무분별한 블로그 정보 수집으로 발생한 문제였다. 소비된 시간 대비 해결하는 방법은 간단해서 좀 허무했고, 꼼꼼히 공부하면 좀 더 빨리 해결할 수 있었을 것 같다는 아쉬움이 있다.