Skip to content
Vitest 2
Main Navigation 가이드API구성브라우저 모드고급
3.2.0
2.1.9
1.6.1
0.34.6

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

한국어

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
Italiano
Polski
Türkçe
čeština
magyar

외관

Sidebar Navigation

Why Browser Mode?

Getting Started

Context API

Interactivity API

Locators

Assertion API

Commands API

이 페이지에서

브라우저 모드 실험적 ​

이 페이지는 Vitest API의 실험적인 브라우저 모드 기능에 대한 정보를 제공합니다. 이 기능을 사용하면 window 및 document와 같은 브라우저 전역 객체에 접근하여 브라우저 환경에서 직접 테스트를 실행할 수 있습니다. 현재 개발 중인 기능이므로 API는 향후 변경될 수 있습니다.

Vitest UIVitest UI

설치 ​

간편한 설정을 위해 vitest init browser 명령어를 사용하여 필요한 종속성을 설치하고 브라우저 구성을 생성할 수 있습니다.

bash
npx vitest init browser
bash
yarn exec vitest init browser
bash
pnpx vitest init browser
bash
bunx vitest init browser

수동 설치 ​

패키지를 수동으로 설치할 수도 있습니다. 브라우저 모드는 기본적으로 기존 브라우저를 재사용하므로 로컬에서 테스트를 실행할 때 추가 E2E(End-to-End) 공급자가 필요하지 않습니다.

bash
npm install -D vitest @vitest/browser
bash
yarn add -D vitest @vitest/browser
bash
pnpm add -D vitest @vitest/browser
bash
bun add -D vitest @vitest/browser

WARNING

그러나 CI(지속적 통합) 환경에서 테스트를 실행하려면 playwright 또는 webdriverio 중 하나를 설치해야 합니다. 또한, 기본 preview 공급자는 Chrome DevTools Protocol 대신 이벤트 시뮬레이션에 의존하므로, 로컬 테스트 시에도 이 두 공급자 중 하나로 전환하는 것을 권장합니다.

이러한 도구 중 하나를 아직 사용하지 않는 경우, Playwright는 병렬 실행을 지원하여 테스트를 더 빠르게 실행할 수 있으므로 Playwright부터 시작하는 것을 권장합니다. 또한 Playwright가 사용하는 Chrome DevTools Protocol은 일반적으로 WebDriver보다 빠릅니다.

::: tabs key:provider == Playwright Playwright는 웹 테스트 및 자동화를 위한 프레임워크입니다.

bash
npm install -D vitest @vitest/browser playwright
bash
yarn add -D vitest @vitest/browser playwright
bash
pnpm add -D vitest @vitest/browser playwright
bash
bun add -D vitest @vitest/browser playwright

== WebdriverIO

WebdriverIO를 사용하면 WebDriver 프로토콜을 통해 로컬에서 테스트를 실행할 수 있습니다.

bash
npm install -D vitest @vitest/browser webdriverio
bash
yarn add -D vitest @vitest/browser webdriverio
bash
pnpm add -D vitest @vitest/browser webdriverio
bash
bun add -D vitest @vitest/browser webdriverio

구성 ​

Vitest 구성에서 브라우저 모드를 활성화하려면 --browser 플래그를 사용하거나 Vitest 구성 파일에서 browser.enabled 필드를 true로 설정할 수 있습니다. 다음은 browser 필드를 사용한 구성 예시입니다.

ts
export default defineConfig({
  test: {
    browser: {
      provider: 'playwright', // 또는 'webdriverio'
      enabled: true,
      name: 'chromium', // 브라우저 이름은 필수입니다.
    },
  },
});

INFO

Vitest는 개발 서버와의 충돌을 피하기 위해 포트 63315를 할당하여 병렬로 실행할 수 있도록 합니다. 이는 browser.api 옵션으로 변경할 수 있습니다.

Vitest 2.1.5부터 CLI는 더 이상 Vite URL을 자동으로 출력하지 않습니다. watch 모드에서 실행할 때 "b"를 눌러 URL을 출력할 수 있습니다.

Vite를 이전에 사용해 본 적이 없다면, 프레임워크의 플러그인이 설치되어 있고 구성에 지정되어 있는지 확인하십시오. 일부 프레임워크는 작동을 위해 추가 구성이 필요할 수 있습니다. 해당 Vite 관련 문서를 확인하여 확인하십시오.

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

export default defineConfig({
  plugins: [vue()],
  test: {
    browser: {
      enabled: true,
      provider: 'playwright',
      name: 'chromium',
    },
  },
});
ts
import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig({
  plugins: [svelte()],
  test: {
    browser: {
      enabled: true,
      provider: 'playwright',
      name: 'chromium',
    },
  },
});
ts
import { defineConfig } from 'vitest/config';
import solidPlugin from 'vite-plugin-solid';

export default defineConfig({
  plugins: [solidPlugin()],
  test: {
    browser: {
      enabled: true,
      provider: 'playwright',
      name: 'chromium',
    },
  },
});
ts
import { defineConfig } from 'vitest/config';
import marko from '@marko/vite';

export default defineConfig({
  plugins: [marko()],
  test: {
    browser: {
      enabled: true,
      provider: 'playwright',
      name: 'chromium',
    },
  },
});

TIP

react는 작동에 플러그인이 필요하지 않지만, preact는 별칭이 작동하도록 추가 구성이 필요합니다.

Node 기반 러너를 사용하여 일부 테스트를 실행해야 하는 경우, 다른 테스트 전략에 대한 별도의 구성으로 워크스페이스 파일을 정의할 수 있습니다.

ts
// vitest.workspace.ts
import { defineWorkspace } from 'vitest/config';

export default defineWorkspace([
  {
    test: {
      // 파일 기반 규칙의 예시입니다.
      // 반드시 따를 필요는 없습니다.
      include: [
        'tests/unit/**/*.{test,spec}.ts',
        'tests/**/*.unit.{test,spec}.ts',
      ],
      name: 'unit',
      environment: 'node',
    },
  },
  {
    test: {
      // 파일 기반 규칙의 예시입니다.
      // 반드시 따를 필요는 없습니다.
      include: [
        'tests/browser/**/*.{test,spec}.ts',
        'tests/**/*.browser.{test,spec}.ts',
      ],
      name: 'browser',
      browser: {
        enabled: true,
        name: 'chrome',
      },
    },
  },
]);

공급자 구성 ​

:::tabs key:provider == Playwright providerOptions 필드를 통해 Vitest가 브라우저를 시작하고 페이지 컨텍스트를 생성하는 방법을 구성할 수 있습니다.

ts
export default defineConfig({
  test: {
    browser: {
      providerOptions: {
        launch: {
          devtools: true,
        },
        context: {
          geolocation: {
            latitude: 45,
            longitude: -30,
          },
          reducedMotion: 'reduce',
        },
      },
    },
  },
});

타입 힌트를 사용하려면 tsconfig.json 파일의 compilerOptions.types에 @vitest/browser/providers/playwright를 추가하십시오. == WebdriverIO providerOptions 필드를 통해 Vitest가 브라우저를 시작할 때 사용할 옵션을 구성할 수 있습니다.

ts
export default defineConfig({
  test: {
    browser: {
      browser: 'chrome',
      providerOptions: {
        region: 'eu',
        capabilities: {
          browserVersion: '27.0',
          platformName: 'Windows 10',
        },
      },
    },
  },
});

타입 힌트를 사용하려면 tsconfig.json 파일의 compilerOptions.types에 @vitest/browser/providers/webdriverio를 추가하십시오. :::

브라우저 옵션 유형 ​

Vitest의 브라우저 옵션은 공급자에 따라 다릅니다. --browser를 전달하고 구성 파일에 이름을 지정하지 않으면 Vitest가 실패합니다. 사용 가능한 옵션:

  • webdriverio는 다음 브라우저를 지원합니다.
    • firefox
    • chrome
    • edge
    • safari
  • playwright는 다음 브라우저를 지원합니다.
    • firefox
    • webkit
    • chromium

브라우저 호환성 ​

Vitest는 Vite 개발 서버를 사용하여 테스트를 실행하므로, esbuild.target 옵션(기본값 esnext)에 지정된 기능만 지원합니다.

기본적으로 Vite는 기본 ES 모듈, 기본 ESM 동적 임포트, 그리고 import.meta를 지원하는 브라우저를 대상으로 합니다. 또한, iframe 간 통신을 위해 BroadcastChannel을 활용합니다.

  • Chrome >=87
  • Firefox >=78
  • Safari >=15.4
  • Edge >=88

테스트 실행 ​

브라우저 옵션에 브라우저 이름을 지정하면 Vitest는 기본적으로 preview를 사용하여 지정된 브라우저를 실행한 다음 거기서 테스트를 실행합니다. preview를 사용하고 싶지 않다면 browser.provider 옵션을 사용하여 사용자 지정 브라우저 공급자를 구성할 수 있습니다.

CLI를 사용하여 브라우저를 지정하려면 --browser 플래그 뒤에 브라우저 이름을 다음과 같이 사용하십시오.

sh
npx vitest --browser=chrome

또는 점 표기법으로 CLI에 브라우저 옵션을 제공할 수 있습니다.

sh
npx vitest --browser.name=chrome --browser.headless

기본적으로 Vitest는 개발을 위해 브라우저 UI를 자동으로 엽니다. 테스트는 중앙의 iframe 내에서 실행됩니다. 선호하는 크기를 선택하거나, 테스트 내에서 page.viewport를 호출하거나, 구성에서 기본값을 설정하여 뷰포트를 구성할 수 있습니다.

헤드리스 ​

헤드리스 모드는 브라우저 모드에서 사용할 수 있는 또 다른 옵션입니다. 헤드리스 모드에서는 브라우저가 사용자 인터페이스 없이 백그라운드에서 실행되므로 자동화된 테스트를 실행하는 데 유용합니다. Vitest의 헤드리스 옵션은 헤드리스 모드를 활성화하거나 비활성화하는 부울 값으로 설정할 수 있습니다.

헤드리스 모드를 사용하면 Vitest는 UI를 자동으로 열지 않습니다. UI를 계속 사용하면서 테스트를 헤드리스로 실행하려면 @vitest/ui 패키지를 설치하고 Vitest를 실행할 때 --ui 플래그를 전달하십시오.

다음은 헤드리스 모드를 활성화하는 구성 예시입니다.

ts
export default defineConfig({
  test: {
    browser: {
      provider: 'playwright',
      enabled: true,
      headless: true,
    },
  },
});

CLI에서 --browser.headless 플래그를 사용하여 헤드리스 모드를 설정할 수도 있습니다.

sh
npx vitest --browser.name=chrome --browser.headless

이 경우 Vitest는 Chrome 브라우저를 사용하여 헤드리스 모드로 실행됩니다.

WARNING

헤드리스 모드는 기본적으로 사용할 수 없습니다. 이 기능을 활성화하려면 playwright 또는 webdriverio 공급자를 사용해야 합니다.

예시 ​

Vitest는 여러 인기 프레임워크의 컴포넌트를 즉시 렌더링할 수 있는 패키지를 제공합니다.

  • vue 컴포넌트를 렌더링하는 vitest-browser-vue
  • svelte 컴포넌트를 렌더링하는 vitest-browser-svelte
  • react 컴포넌트를 렌더링하는 vitest-browser-react

사용하는 프레임워크가 없다면 직접 패키지를 만들어도 좋습니다. 이는 프레임워크 렌더러와 page.elementLocator API를 감싸는 간단한 래퍼입니다. 이 페이지에 링크를 추가해 드리겠습니다. 이름이 vitest-browser-로 시작하는지 확인하십시오.

컴포넌트 렌더링 및 요소 찾기 외에도 어설션도 필요합니다. Vitest는 @testing-library/jest-dom 라이브러리를 번들로 제공하여 다양한 DOM 어설션을 즉시 사용할 수 있도록 합니다. 자세한 내용은 어설션 API를 참조하십시오.

ts
import { expect } from 'vitest';
import { page } from '@vitest/browser/context';
// 요소가 제대로 렌더링되었는지 확인합니다.
await expect.element(page.getByText('Hello World')).toBeInTheDocument();

Vitest는 테스트에 유용할 수 있는 작은 유틸리티 세트와 함께 컨텍스트 API를 노출합니다. 예를 들어, 요소를 클릭하거나 입력 필드에 텍스트를 입력하는 것과 같은 상호 작용을 해야 하는 경우 @vitest/browser/context에서 userEvent를 사용할 수 있습니다. 자세한 내용은 상호 작용 API를 참조하십시오.

ts
import { page, userEvent } from '@vitest/browser/context';
await userEvent.fill(page.getByLabelText(/username/i), 'Alice');
// 또는 단순히 locator.fill
await page.getByLabelText(/username/i).fill('Alice');
ts
import { render } from 'vitest-browser-vue';
import Component from './Component.vue';

test('properly handles v-model', async () => {
  const screen = render(Component);

  // 초기 상태를 확인합니다.
  await expect
    .element(screen.getByText('Hi, my name is Alice'))
    .toBeInTheDocument();

  // 연관된 레이블을 검색하여 입력 DOM 노드를 찾습니다.
  const usernameInput = screen.getByLabelText(/username/i);

  // 입력 필드에 이름을 입력합니다. 이는 입력 필드가 올바르게 채워졌는지 이미
  // 유효성 검사를 수행하므로 값을 수동으로 확인할 필요가 없습니다.
  await usernameInput.fill('Bob');

  await expect
    .element(screen.getByText('Hi, my name is Bob'))
    .toBeInTheDocument();
});
ts
import { render } from 'vitest-browser-svelte';
import { expect, test } from 'vitest';

import Greeter from './greeter.svelte';

test('greeting appears on click', async () => {
  const screen = render(Greeter, { name: 'World' });

  const button = screen.getByRole('button');
  await button.click();
  const greeting = screen.getByText(/hello world/iu);

  await expect.element(greeting).toBeInTheDocument();
});
tsx
import { render } from 'vitest-browser-react';
import Fetch from './fetch';

test('loads and displays greeting', async () => {
  // React 요소를 DOM에 렌더링합니다.
  const screen = render(<Fetch url="/greeting" />);

  await screen.getByText('Load Greeting').click();
  // 요소를 찾지 못할 경우 오류가 발생하기 전에 대기합니다.
  const heading = screen.getByRole('heading');

  // 알림 메시지가 정확한지 확인합니다.
  await expect.element(heading).toHaveTextContent('hello there');
  await expect.element(screen.getByRole('button')).toBeDisabled();
});

Vitest는 모든 프레임워크를 즉시 지원하지는 않지만, 외부 도구를 사용하여 이러한 프레임워크로 테스트를 실행할 수 있습니다. 또한 커뮤니티에서 자체 vitest-browser 래퍼를 만들도록 권장합니다. 만약 있다면 위 예시에 추가해 주십시오.

지원되지 않는 프레임워크의 경우 testing-library 패키지를 사용하는 것을 권장합니다.

  • preact 컴포넌트를 렌더링하는 @testing-library/preact
  • solid 컴포넌트를 렌더링하는 @solidjs/testing-library
  • marko 컴포넌트를 렌더링하는 @marko/testing-library

WARNING

testing-library는 @testing-library/user-event 패키지를 제공합니다. 이 패키지는 이벤트를 실제로 트리거하는 대신 시뮬레이션하므로 직접 사용하는 것을 권장하지 않습니다. 대신, 내부적으로 Chrome DevTools Protocol 또는 Webdriver(공급자에 따라 다름)를 사용하는 @vitest/browser/context에서 가져온 userEvent를 사용하십시오.

tsx
// @testing-library/preact 예시 기반
// https://testing-library.com/docs/preact-testing-library/example

import { h } from 'preact';
import { page } from '@vitest/browser/context';
import { render } from '@testing-library/preact';

import HiddenMessage from '../hidden-message';

test('shows the children when the checkbox is checked', async () => {
  const testMessage = 'Test Message';

  const { baseElement } = render(<HiddenMessage>{testMessage}</HiddenMessage>);

  const screen = page.elementLocator(baseElement);

  // .query()는 요소를 찾으면 반환하고, 찾을 수 없으면 null을 반환합니다.
  // .element()는 요소를 찾으면 반환하고, 찾을 수 없으면 오류를 발생시킵니다.
  expect(screen.getByText(testMessage).query()).not.toBeInTheDocument();

  // 쿼리는 정규식을 허용하여 선택자를 콘텐츠 변경에 더 강하게 만들 수 있습니다.
  await screen.getByLabelText(/show/i).click();

  await expect.element(screen.getByText(testMessage)).toBeInTheDocument();
});
tsx
// @testing-library/solid API 기반
// https://testing-library.com/docs/solid-testing-library/api

import { render } from '@testing-library/solid';

it('uses params', async () => {
  const App = () => (
    <>
      <Route
        path="/ids/:id"
        component={() => (
          <p>
            Id:
            {useParams()?.id}
          </p>
        )}
      />
      <Route path="/" component={() => <p>Start</p>} />
    </>
  );
  const { baseElement } = render(() => <App />, { location: 'ids/1234' });
  const screen = page.elementLocator(baseElement);

  await expect.screen(screen.getByText('Id: 1234')).toBeInTheDocument();
});
ts
// @testing-library/marko API 기반
// https://testing-library.com/docs/marko-testing-library/api

import { render, screen } from '@marko/testing-library';
import Greeting from './greeting.marko';

test('renders a message', async () => {
  const { baseElement } = await render(Greeting, { name: 'Marko' });
  const screen = page.elementLocator(baseElement);
  await expect.element(screen.getByText(/Marko/)).toBeInTheDocument();
  await expect.element(container.firstChild).toMatchInlineSnapshot(`
    <h1>Hello, Marko!</h1>
  `);
});

제한 사항 ​

스레드 차단 다이얼로그 ​

Vitest 브라우저를 사용할 때 alert 또는 confirm과 같은 스레드 차단 다이얼로그는 기본적으로 사용할 수 없다는 점에 유의해야 합니다. 이는 웹 페이지를 차단하여 Vitest가 페이지와 계속 통신할 수 없게 되어 실행이 중단되기 때문입니다.

이러한 상황에서 Vitest는 이러한 API에 대한 기본 반환 값을 가진 기본 모의(mock)를 제공합니다. 이는 사용자가 실수로 동기 팝업 웹 API를 사용하더라도 실행이 중단되지 않도록 보장합니다. 그러나 더 나은 경험을 위해 사용자가 이러한 웹 API를 모의하는 것이 여전히 권장됩니다. 자세한 내용은 모의(Mocking)를 참조하십시오.

Pager
이전Why Browser Mode?
다음Context API

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2021-Present Vitest Team

https://v2.vitest.dev/guide/

MIT 라이선스 하에 배포되었습니다.

Copyright (c) 2021-Present Vitest Team