본문 바로가기
TECH

Playwright / MSW 🧪

by Stella-Park 2025. 9. 8.
728x90

PlaywrightMSW(Mock Service Worker)는 웹 개발과 테스트에서 많이 사용하는 도구 중 하나다.

Playwright와 MSW(Mock Service Worker)를 함께 사용하는 것은 프론트엔드 E2E 및 통합 테스트 환경에서 매우 강력한 조합이 될 수 있다.

 

Playwright

Playwright는 Microsoft에서 만든 오픈 소스 엔드투엔드(E2E) 테스트 프레임워크이다.

브라우저를 자동으로 제어하여 실제 사용자처럼 웹 애플리케이션을 테스트할 수 있다.

화면에 어떤 버튼, 입력값을 입력했을 때 오류 케이스, 알럿, 페이지 이동까지 어떻게 이루어져야 하는지 테스트할 수 있다.

단, 오래된 맥 (2024년 기준 2019년 맥북 프로) 에서는 실행되지 않았다.

 

  • 멀티 브라우저 지원: Chromium(Chrome, Edge), Firefox, WebKit(Safari) 등 주요 브라우저를 지원
  • 헤드리스/헤드풀 모드: GUI 없이 빠르게 실행하거나 실제 브라우저처럼 창을 띄워 실행 가능
  • 크로스 플랫폼: Windows, macOS, Linux 모두 지원
  • 자동 대기: DOM 요소가 준비될 때까지 자동으로 기다리므로 flakiness가 감소
  • 병렬 실행 & 멀티 컨텍스트: 여러 브라우저 세션을 동시에 실행 가능
  • 모바일 시뮬레이션: iPhone, Pixel 등의 디바이스 에뮬레이션을 제공
  • 비디오/스크린샷 기록: 실패 시 디버깅에 도움을 주는 비디오, 스크린샷 저장 기능
import { expect, test } from '@playwright/test'

test('투자 성향 테스트 결과가 존재하는 경우', async ({ page }) => {
  await withAuthContext(page, async () => {
    const entryUrl = getUrl(['empty_user', 'intent', 'intent_exists'], '/intent', {
      productId: '15',
    })

    await test.step('기존 결과 표시', async () => {
      await page.goto(entryUrl)

      await expect(page.getByText('공격형')).toBeVisible()
      await expect(page.getByTestId('intent-graph')).toBeVisible()

      const keepButton = page.getByText('현재 성향 유지')
      await expect(keepButton).toBeVisible()
      await expect(keepButton).toBeEnabled()
    })

    await test.step('재설문 시도', async () => {
      const retryButton = page.getByText(/^재설문$/)
      await expect(retryButton).toBeVisible()
      await expect(retryButton).toBeEnabled()

      await retryButton.click()
      await page.waitForURL('/intent/purpose?*', {
        waitUntil: 'networkidle',
      })
    })
  })
})

 

 

MSW (Mock Service Worker)

MSW는 서비스 워커를 이용해 네트워크 요청을 가로채고, 가짜(mock) 응답으로 대체할 수 있는 도구이다.

프론트엔드 개발과 테스트에서 백엔드 API를 대체하거나 시뮬레이션할 때 주로 사용된다.

 

  • 브라우저 기반 가상 API: 실제 네트워크 요청을 서비스 워커 레벨에서 가로챔
  • Node.js 지원: 서버 사이드(Node, Jest 등)에서도 mock 가능
  • 실제 네트워크와 유사한 환경: XHR/fetch 같은 요청을 가로채기 때문에 실제 API 호출과 거의 동일한 조건을 제공
  • 테스트 신뢰성 강화: API 서버의 상태나 연결 문제에 영향을 받지 않음
  • 백엔드 개발 지연 시 활용: API가 준비되기 전 프론트엔드 개발이 가능

 

Playwright + MSW 조합

  • 다양한 API 응답 시나리오(성공/실패/지연)를 쉽게 시뮬레이션 가능
  • 외부 API 의존성을 제거하고 안정적인 테스트 환경을 구축 가능
  • CI/CD에서 flaky하지 않은 테스트를 유지 가능

 

Playwright + MSW 조합의 장점

1. 네트워크 안정성과 속도 확보

Playwright는 실제 브라우저 환경에서 테스트를 실행하지만, 외부 API나 백엔드 서버에 의존하면 테스트가 느리거나 불안정해질 수 있는데 이 때 MSW를 사용하면:

  • 네트워크 요청을 가로채어 가짜 응답(mock)을 반환할 수 있음
  • 외부 서비스가 다운되었거나 API가 변경되어도 테스트는 계속 안정적으로 작동
  • 테스트 실행 속도가 훨씬 빨라짐

2. 더 쉬운 상태 시뮬레이션 (에러/엣지 케이스 등)

실제 API로는 시뮬레이션하기 어려운 상황을 MSW로 쉽게 구현할 수 있음

예:

  • 로그인 API가 401 Unauthorized를 반환하는 상황
  • 백엔드에서 특정 필드가 누락된 경우
  • 서버 응답이 느려지는 상황(인위적으로 delay 추가)

이런 케이스들을 쉽게 mock 하여 UI와 사용자 흐름을 테스트할 수 있음

3. E2E와 Mocks의 통합

Playwright 내에서 runtime 중에 MSW 핸들러를 동적으로 바꾸는 것도 가능하다.

이를 통해 하나의 E2E 테스트 안에서도 다양한 mock 시나리오를 시도할 수 있다.

// Playwright 테스트 내에서 MSW 핸들러 동적으로 등록
await page.evaluate(() => {
  window.msw.use(
    rest.get('/api/user', (req, res, ctx) => {
      return res(ctx.status(500));
    })
  );
});


// 프로젝트 내에서 사용한 방법
import { HttpResponse } from 'msw'
export function success<T>(data: T) {
  return HttpResponse.json({
    details: null,
    errors: null,
    result: data,
    code: 0,
    message: '정상 처리되었습니다.',
  })
}

import type { ContractProgress } from '$src/lib/domain'
import { http } from 'msw'
import { success } from '../../../response'

export function createProgressHandlers(progress: ContractProgress) {
  return [
    http.get('https://api.test.com/contract/progress', async () => {
      return success([progress])
    }),
    http.get(`https://api.test.com/contract/progress/${progress.productId}`, async () => {
      return success(progress)
    }),
  ]
}

 

4. 로컬 개발과 테스트에서의 일관성

MSW는 개발 모드에서도 사용할 수 있기 때문에:

  • 개발 중에도 API를 기다리지 않고 UI 작업을 진행할 수 있고,
  • 동일한 핸들러(mock 응답)를 테스트에서도 재사용하여 개발 ↔ 테스트 간 응답 불일치 문제를 줄일 수 있다.

 

정리

항목 장점
안정성 API 의존도 제거, flaky 테스트 감소
속도 API 대기 없이 즉시 응답, 테스트 시간 단축
유연성 에러/엣지 케이스 쉽게 시뮬레이션 가능
일관성 개발-테스트 동일한 mock 설정 공유 가능
유지보수 API 변경에도 테스트 영향 최소화

 

 

이상 스텔라였습니다 ✍🏻

 

 

 

 

728x90

'TECH' 카테고리의 다른 글

🧠 Stack Overflow의 사용 통계 변화 (2008–2025)  (0) 2025.10.28
DOM에 관하여  (0) 2025.10.27
rebase ↹  (0) 2025.09.05
Tailwind CSS 🪮  (1) 2025.09.03
의존성 분류에 대해서 ➗  (0) 2025.09.01