Browser-Modus Experimentell
Diese Seite enthält Informationen zur experimentellen Browser-Modus-Funktion in der Vitest-API. Sie ermöglicht es Ihnen, Ihre Tests nativ im Browser auszuführen und dabei auf globale Browser-Objekte wie window und document zuzugreifen. Diese Funktion befindet sich derzeit in der Entwicklung, und die APIs können sich zukünftig ändern.
TIP
Wenn Sie Dokumentation zu expect, vi oder allgemeinen APIs wie Testprojekten oder Typüberprüfung suchen, lesen Sie den Leitfaden "Erste Schritte".


Installation
Für eine einfache Einrichtung können Sie den Befehl vitest init browser verwenden, um die erforderlichen Abhängigkeiten zu installieren und die Browser-Konfiguration zu erstellen.
npx vitest init browseryarn exec vitest init browserpnpx vitest init browserbunx vitest init browserManuelle Installation
Sie können Pakete auch manuell installieren. Standardmäßig benötigt der Browser-Modus keinen zusätzlichen E2E-Testanbieter, um Tests lokal auszuführen, da er Ihren vorhandenen Browser wiederverwendet.
npm install -D vitest @vitest/browseryarn add -D vitest @vitest/browserpnpm add -D vitest @vitest/browserbun add -D vitest @vitest/browserWARNING
Um Tests in der CI (Continuous Integration) auszuführen, müssen Sie jedoch entweder playwright oder webdriverio installieren. Wir empfehlen zudem, für lokale Tests zu einem dieser Tools zu wechseln, anstatt den Standard-preview-Anbieter zu verwenden, da dieser Ereignisse simuliert, anstatt das Chrome DevTools Protocol zu nutzen.
Wenn Sie noch keines dieser Tools verwenden, empfehlen wir, mit Playwright zu beginnen, da es die parallele Ausführung unterstützt, was Ihre Tests beschleunigt. Zusätzlich verwendet Playwright das Chrome DevTools Protocol, das im Allgemeinen schneller ist als WebDriver.
::: tabs key:provider == Playwright Playwright ist ein Framework für Webtests und Automatisierung.
npm install -D vitest @vitest/browser playwrightyarn add -D vitest @vitest/browser playwrightpnpm add -D vitest @vitest/browser playwrightbun add -D vitest @vitest/browser playwright== WebdriverIO
WebdriverIO ermöglicht Ihnen, Tests lokal mit dem WebDriver-Protokoll auszuführen.
npm install -D vitest @vitest/browser webdriverioyarn add -D vitest @vitest/browser webdriveriopnpm add -D vitest @vitest/browser webdriveriobun add -D vitest @vitest/browser webdriverioKonfiguration
Um den Browser-Modus in Ihrer Vitest-Konfiguration zu aktivieren, setzen Sie das Feld browser.enabled in Ihrer Vitest-Konfigurationsdatei auf true. Hier ist ein Beispiel für eine Konfiguration, die das browser-Feld nutzt:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright', // oder 'webdriverio'
enabled: true,
// mindestens eine Instanz muss angegeben werden
instances: [{ browser: 'chromium' }],
},
},
});INFO
Vitest weist Port 63315 zu, um Konflikte mit dem Entwicklungsserver zu vermeiden und beide parallel ausführen zu können. Sie können dies mit der Option browser.api ändern.
Seit Vitest 2.1.5 gibt die CLI die Vite-URL nicht mehr automatisch aus. Sie können "b" drücken, um die URL im Watch-Modus anzuzeigen.
Wenn Sie Vite noch nicht verwendet haben, stellen Sie sicher, dass das Plugin Ihres Frameworks installiert und in der Konfiguration angegeben ist. Einige Frameworks erfordern möglicherweise zusätzliche Konfiguration, um zu funktionieren – überprüfen Sie deren Dokumentation zu Vite, um sicherzugehen.
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
plugins: [svelte()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import solidPlugin from 'vite-plugin-solid';
export default defineConfig({
plugins: [solidPlugin()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import marko from '@marko/vite';
export default defineConfig({
plugins: [marko()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});Wenn Sie einige Tests mit einem Node-basierten Runner ausführen müssen, können Sie eine projects-Option mit separaten Konfigurationen für verschiedene Teststrategien definieren:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
test: {
// ein Beispiel für eine dateibasierte Konvention,
// der Sie nicht folgen müssen
include: [
'tests/unit/**/*.{test,spec}.ts',
'tests/**/*.unit.{test,spec}.ts',
],
name: 'unit',
environment: 'node',
},
},
{
test: {
// ein Beispiel für eine dateibasierte Konvention,
// der Sie nicht folgen müssen
include: [
'tests/browser/**/*.{test,spec}.ts',
'tests/**/*.browser.{test,spec}.ts',
],
name: 'browser',
browser: {
enabled: true,
instances: [{ browser: 'chromium' }],
},
},
},
],
},
});Browser-Optionstypen
Die Browser-Option in Vitest hängt vom Anbieter ab. Vitest schlägt fehl, wenn Sie --browser übergeben und dessen Namen nicht in der Konfigurationsdatei angeben. Verfügbare Optionen:
webdriveriounterstützt diese Browser:firefoxchromeedgesafari
playwrightunterstützt diese Browser:firefoxwebkitchromium
TypeScript
Standardmäßig erkennt TypeScript die Anbieteroptionen und erweiterten expect-Eigenschaften nicht. Wenn Sie keine Anbieter verwenden, stellen Sie sicher, dass @vitest/browser/matchers irgendwo in Ihren Tests, Setup-Datei oder einer Konfigurationsdatei referenziert wird, um die zusätzlichen expect-Definitionen zu erkennen. Wenn Sie benutzerdefinierte Anbieter verwenden, stellen Sie sicher, dass Sie @vitest/browser/providers/playwright oder @vitest/browser/providers/webdriverio zur selben Datei hinzufügen, damit TypeScript Definitionen für benutzerdefinierte Optionen erkennen kann:
/// <reference types="@vitest/browser/matchers" />/// <reference types="@vitest/browser/providers/playwright" />/// <reference types="@vitest/browser/providers/webdriverio" />Alternativ können Sie sie auch zum Feld compilerOptions.types in Ihrer tsconfig.json-Datei hinzufügen. Beachten Sie, dass jede Angabe in diesem Feld das automatische Laden von @types/*-Paketen deaktiviert.
{
"compilerOptions": {
"types": ["@vitest/browser/matchers"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/playwright"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/webdriverio"]
}
}Browser-Kompatibilität
Vitest verwendet den Vite-Entwicklungsserver, um Ihre Tests auszuführen. Daher unterstützen wir nur Funktionen, die in der Option esbuild.target (esnext standardmäßig) angegeben sind.
Standardmäßig zielt Vite auf Browser ab, die native ES-Module, native ESM Dynamic Import und import.meta unterstützen. Darüber hinaus verwenden wir BroadcastChannel zur Kommunikation zwischen Iframes:
- Chrome >=87
- Firefox >=78
- Safari >=15.4
- Edge >=88
Tests ausführen
Wenn Sie einen Browsernamen in der Browser-Option angeben, versucht Vitest standardmäßig, den angegebenen Browser mit preview auszuführen und die Tests dann dort auszuführen. Wenn Sie preview nicht verwenden möchten, können Sie den benutzerdefinierten Browser-Anbieter über die Option browser.provider konfigurieren.
Um einen Browser über die CLI anzugeben, verwenden Sie das Flag --browser gefolgt vom Browsernamen, wie folgt:
npx vitest --browser=chromiumOder Sie können Browser-Optionen mit der Punktnotation an die CLI übergeben:
npx vitest --browser.headlessWARNING
Seit Vitest 3.2 schlägt Vitest fehl, wenn Sie die Option browser nicht in Ihrer Konfiguration haben, aber das Flag --browser angeben, da es nicht automatisch erkennen kann, ob die Konfiguration für Browser- oder Node.js-Tests vorgesehen ist.
Standardmäßig öffnet Vitest automatisch die Browser-Benutzeroberfläche für die Entwicklung. Ihre Tests werden in einem Iframe in der Mitte ausgeführt. Sie können den Viewport konfigurieren, indem Sie die gewünschten Abmessungen auswählen, page.viewport innerhalb des Tests aufrufen oder Standardwerte in der Konfiguration festlegen.
Headless
Der Headless-Modus ist eine weitere Option, die im Browser-Modus verfügbar ist. Im Headless-Modus läuft der Browser im Hintergrund ohne Benutzeroberfläche, was ihn nützlich für die Ausführung automatisierter Tests macht. Die Headless-Option in Vitest kann als boolescher Wert festgelegt werden, um den Headless-Modus zu aktivieren oder zu deaktivieren.
Bei Verwendung des Headless-Modus öffnet Vitest die Benutzeroberfläche nicht automatisch. Wenn Sie die Benutzeroberfläche weiterhin verwenden möchten, aber Tests im Headless-Modus ausführen möchten, können Sie das Paket @vitest/ui installieren und das Flag --ui beim Ausführen von Vitest übergeben.
Hier ist ein Beispiel für eine Konfiguration, die den Headless-Modus aktiviert:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright',
enabled: true,
headless: true,
},
},
});Sie können den Headless-Modus auch über das Flag --browser.headless in der CLI einstellen, wie folgt:
npx vitest --browser.headlessIn diesem Fall wird Vitest im Headless-Modus mit dem Chrome-Browser ausgeführt.
WARNING
Der Headless-Modus ist standardmäßig nicht verfügbar. Sie müssen entweder playwright oder webdriverio als Anbieter verwenden, um diese Funktion zu aktivieren.
Beispiele
Standardmäßig benötigen Sie keine externen Pakete, um mit dem Browser-Modus zu arbeiten:
import { expect, test } from 'vitest';
import { page } from '@vitest/browser/context';
import { render } from './my-render-function.js';
test('properly handles form inputs', async () => {
render(); // DOM-Elemente rendern
// Bestätigt den Anfangszustand.
await expect
.element(page.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Das DOM-Eingabeelement durch Abfragen des zugehörigen Labels ermitteln.
const usernameInput = page.getByLabelText(/username/i);
// Den Namen in das Eingabefeld eingeben. Dies validiert bereits, dass die Eingabe
// korrekt ausgefüllt ist, es ist nicht notwendig, den Wert manuell zu überprüfen.
await usernameInput.fill('Bob');
await expect
.element(page.getByText('Hi, my name is Bob'))
.toBeInTheDocument();
});Vitest bietet jedoch auch Pakete zum Rendern von Komponenten für mehrere beliebte Frameworks standardmäßig:
vitest-browser-vuezum Rendern von Vue-Komponentenvitest-browser-sveltezum Rendern von Svelte-Komponentenvitest-browser-reactzum Rendern von React-Komponenten
Community-Pakete sind für andere Frameworks verfügbar:
vitest-browser-litzum Rendern von Lit-Komponentenvitest-browser-preactzum Rendern von Preact-Komponenten
Wenn Ihr Framework nicht unterstützt wird, können Sie gerne Ihr eigenes Paket erstellen – es ist ein einfacher Wrapper um den Framework-Renderer und die page.elementLocator-API. Wir werden einen Link dazu auf dieser Seite hinzufügen. Stellen Sie sicher, dass der Name mit vitest-browser- beginnt.
Neben dem Rendern von Komponenten und dem Auffinden von Elementen müssen Sie auch Assertions treffen. Vitest basiert auf der Bibliothek @testing-library/jest-dom, um eine breite Palette von DOM-Assertions standardmäßig bereitzustellen. Lesen Sie mehr unter der Assertions API.
import { expect } from 'vitest';
import { page } from '@vitest/browser/context';
// Element wird korrekt gerendert
await expect.element(page.getByText('Hello World')).toBeInTheDocument();Vitest stellt eine Context API mit einer kleinen Auswahl an Hilfsprogrammen zur Verfügung, die in Tests nützlich sein könnten. Wenn Sie beispielsweise eine Interaktion durchführen müssen, wie das Klicken auf ein Element oder das Eingeben von Text in ein Eingabefeld, können Sie userEvent von @vitest/browser/context verwenden. Lesen Sie mehr unter der Interactivity API.
import { page, userEvent } from '@vitest/browser/context';
await userEvent.fill(page.getByLabelText(/username/i), 'Alice');
// oder einfach locator.fill
await page.getByLabelText(/username/i).fill('Alice');import { render } from 'vitest-browser-vue';
import Component from './Component.vue';
test('properly handles v-model', async () => {
const screen = render(Component);
// Bestätigt den Anfangszustand.
await expect
.element(screen.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Das DOM-Eingabeelement durch Abfragen des zugehörigen Labels ermitteln.
const usernameInput = screen.getByLabelText(/username/i);
// Den Namen in das Eingabefeld eingeben. Dies validiert bereits, dass die Eingabe
// korrekt ausgefüllt ist, es ist nicht notwendig, den Wert manuell zu überprüfen.
await usernameInput.fill('Bob');
await expect
.element(screen.getByText('Hi, my name is Bob'))
.toBeInTheDocument();
});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();
});import { render } from 'vitest-browser-react';
import Fetch from './fetch';
test('loads and displays greeting', async () => {
// Rendert ein React-Element in den DOM
const screen = render(<Fetch url="/greeting" />);
await screen.getByText('Load Greeting').click();
// warten, bevor ein Fehler ausgelöst wird, falls ein Element nicht gefunden werden kann
const heading = screen.getByRole('heading');
// überprüfen, ob die Begrüßung korrekt ist
await expect.element(heading).toHaveTextContent('hello there');
await expect.element(screen.getByRole('button')).toBeDisabled();
});import { render } from 'vitest-browser-lit';
import { html } from 'lit';
import './greeter-button';
test('greeting appears on click', async () => {
const screen = render(html`<greeter-button name="World"></greeter-button>`);
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});import { render } from 'vitest-browser-preact';
import { createElement } from 'preact';
import Greeting from './Greeting';
test('greeting appears on click', async () => {
const screen = render(<Greeting />);
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});Vitest unterstützt nicht alle Frameworks standardmäßig, aber Sie können externe Tools verwenden, um Tests mit diesen Frameworks auszuführen. Wir ermutigen auch die Community, eigene vitest-browser-Wrapper zu erstellen – wenn Sie einen haben, können Sie ihn gerne zu den obigen Beispielen hinzufügen.
Für nicht unterstützte Frameworks empfehlen wir die Verwendung von testing-library-Paketen:
@solidjs/testing-libraryzum Rendern von Solid-Komponenten@marko/testing-libraryzum Rendern von Marko-Komponenten
Weitere Beispiele finden Sie auch im Repository browser-examples.
WARNING
testing-library bietet ein Paket @testing-library/user-event. Wir empfehlen, es nicht direkt zu verwenden, da es Ereignisse simuliert, anstatt sie tatsächlich auszulösen – verwenden Sie stattdessen userEvent, importiert von @vitest/browser/context, das intern das Chrome DevTools Protocol oder Webdriver (je nach Anbieter) verwendet.
// basierend auf der @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();
});// basierend auf der @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();
expect(container.firstChild).toMatchInlineSnapshot(`
<h1>Hello, Marko!</h1>
`);
});Einschränkungen
Thread-blockierende Dialoge
Bei der Verwendung des Vitest Browser-Modus ist es wichtig zu beachten, dass Thread-blockierende Dialoge wie alert oder confirm nicht nativ verwendet werden können. Dies liegt daran, dass sie die Webseite blockieren, was bedeutet, dass Vitest die Kommunikation mit der Seite nicht fortsetzen kann, wodurch die Ausführung blockiert wird.
In solchen Situationen bietet Vitest Standard-Mocks mit vordefinierten Rückgabewerten für diese APIs. Dies stellt sicher, dass die Ausführung nicht blockiert wird, wenn der Benutzer versehentlich synchrone Dialog-APIs verwendet. Es wird jedoch weiterhin empfohlen, diese Web-APIs für ein besseres Verhalten zu mocken. Lesen Sie mehr unter Mocking.