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

本頁導覽

瀏覽器模式 Experimental ​

本頁提供 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 提供者即可在本地執行測試,因為它會重用您現有的瀏覽器。

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 提供者,因為 preview 依賴於模擬事件,而非使用 Chrome DevTools Protocol。

如果您尚未接觸這些工具,我們建議您從 Playwright 開始,因為它支援平行執行,能讓您的測試執行得更快。此外,Playwright 使用的 Chrome DevTools Protocol 通常比 WebDriver 更快。

::: tabs key:provider == Playwright Playwright 是一個用於 Web 測試和自動化的框架。

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 協定(protocol)在本地執行測試。

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。在監聽模式下執行時,您可以按「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',
        },
      },
    },
  },
});

若要啟用類型提示,請將 @vitest/browser/providers/playwright 新增至 tsconfig.json 檔案中的 compilerOptions.types。 == WebdriverIO 您可以透過 providerOptions 欄位配置 Vitest 在啟動瀏覽器時應使用的選項:

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

若要啟用類型提示,請將 @vitest/browser/providers/webdriverio 新增至 tsconfig.json 檔案中的 compilerOptions.types。 :::

瀏覽器選項類型 ​

Vitest 中的瀏覽器選項取決於所選的提供者。如果您傳遞 --browser 但未在配置檔中指定其名稱,Vitest 將會失敗。可用選項:

  • webdriverio 支援以下瀏覽器:
    • firefox
    • chrome
    • edge
    • safari
  • playwright 支援以下瀏覽器:
    • firefox
    • webkit
    • chromium

瀏覽器相容性 ​

Vitest 使用 Vite 開發伺服器來執行您的測試,因此我們僅支援 esbuild.target 選項中指定的功能(預設為 esnext)。

預設情況下,Vite 針對支援原生 ES 模組、原生 ESM 動態導入和 import.meta 的瀏覽器。除此之外,我們還利用 BroadcastChannel 在 iframe 之間進行通訊:

  • 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 或在配置中設定預設值來配置視窗(viewport)。

無頭模式 ​

無頭模式(headless)是瀏覽器模式中另一個可用的選項。在無頭模式下,瀏覽器在後台執行,沒有使用者介面,這使得它對於執行自動化測試非常有用。Vitest 中的 headless 選項可以設定為布林值以啟用或禁用無頭模式。

使用無頭模式時,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 提供開箱即用的套件,用於渲染多個流行框架的組件:

  • vitest-browser-vue 用於渲染 vue 組件
  • vitest-browser-svelte 用於渲染 svelte 組件
  • vitest-browser-react 用於渲染 react 組件

如果您的框架未被支援,請隨時建立您自己的套件 - 它只是框架渲染器和 page.elementLocator API 的簡單包裝(wrapper)。我們將在此頁面上新增連結。請確保其名稱以 vitest-browser- 開頭。

除了渲染組件和定位元素之外,您還需要進行斷言(assertion)。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 套件:

  • @testing-library/preact 用於渲染 preact 組件
  • @solidjs/testing-library 用於渲染 solid 組件
  • @marko/testing-library 用於渲染 marko 組件

WARNING

testing-library 提供了一個套件 @testing-library/user-event。我們不建議直接使用它,因為它模擬事件而不是實際觸發它們 - 相反,請使用從 @vitest/browser/context 導入的 userEvent,它在底層使用 Chrome DevTools Protocol 或 Webdriver(取決於提供者)。

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 等執行緒阻塞(thread-blocking)對話框無法原生使用。這是因為它們會阻塞網頁,導致 Vitest 無法繼續與頁面通訊,進而使執行掛起。

在這種情況下,Vitest 為這些 API 提供了預設的模擬(mock),並帶有預設的回傳值。這確保了即使使用者意外使用同步彈出式 Web API,執行也不會掛起。然而,仍然建議使用者模擬這些 Web API 以獲得更好的體驗。請參閱模擬以了解更多資訊。

Pager
上一頁Why Browser Mode?
下一頁Context API

以 MIT 授權條款 發布。

版權所有 (c) 2021-Present Vitest Team

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

以 MIT 授權條款 發布。

版權所有 (c) 2021-Present Vitest Team