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 auf globale Browser-Objekte wie window und document zuzugreifen. Diese Funktion befindet sich derzeit in der Entwicklung, und die APIs können sich in Zukunft ändern.


Installation
Zur Vereinfachung der Einrichtung können Sie den Befehl vitest init browser verwenden, um die erforderlichen Abhängigkeiten zu installieren und eine Browser-Konfiguration zu generieren.
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-Anbieter, um Tests lokal auszuführen, da er Ihren vorhandenen Browser nutzt.
npm install -D vitest @vitest/browseryarn add -D vitest @vitest/browserpnpm add -D vitest @vitest/browserbun add -D vitest @vitest/browserWARNING
Um Tests in CI (Continuous Integration) auszuführen, müssen Sie jedoch entweder playwright oder webdriverio installieren. Wir empfehlen auch, für lokale Tests eines dieser Tools zu verwenden, anstatt den Standardanbieter preview zu nutzen, da dieser auf der Simulation von Ereignissen basiert und nicht das Chrome DevTools Protocol verwendet.
Wenn Sie noch keines dieser Tools verwenden, empfehlen wir, mit Playwright zu beginnen, da es die parallele Ausführung unterstützt und Ihre Tests beschleunigt. Zudem ist das Chrome DevTools Protocol, das Playwright nutzt, in der Regel schneller als WebDriver.
::: tabs key:provider == Playwright Playwright ist ein Framework für Web-Tests 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 es 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, können Sie das --browser-Flag verwenden oder das Feld browser.enabled in Ihrer Vitest-Konfigurationsdatei auf true setzen. Hier ist ein Beispiel für eine Konfiguration mit dem browser-Feld:
export default defineConfig({
test: {
browser: {
provider: 'playwright', // oder 'webdriverio'
enabled: true,
name: 'chromium', // Browser-Name ist erforderlich
},
},
});INFO
Vitest belegt Port 63315, um Konflikte mit dem Entwicklungsserver zu vermeiden, sodass Sie beide parallel ausführen können. Sie können dies mit der Option browser.api ändern.
Seit Vitest 2.1.5 druckt 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 eingetragen ist. Einige Frameworks erfordern möglicherweise zusätzliche Konfiguration, um zu funktionieren – konsultieren Sie deren Vite-bezogene Dokumentation, um dies sicherzustellen.
import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
});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',
},
},
});import { defineConfig } from 'vitest/config';
import solidPlugin from 'vite-plugin-solid';
export default defineConfig({
plugins: [solidPlugin()],
test: {
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
});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 benötigt kein Plugin, um zu funktionieren, aber preact erfordert zusätzliche Konfiguration, um Aliase zu ermöglichen.
Wenn Sie einige Tests mit einem Node-basierten Runner ausführen müssen, können Sie eine Workspace-Datei mit separaten Konfigurationen für verschiedene Teststrategien definieren:
// vitest.workspace.ts
import { defineWorkspace } from 'vitest/config';
export default defineWorkspace([
{
test: {
// ein Beispiel für eine dateibasierte Konvention,
// Sie müssen ihr nicht folgen
include: [
'tests/unit/**/*.{test,spec}.ts',
'tests/**/*.unit.{test,spec}.ts',
],
name: 'unit',
environment: 'node',
},
},
{
test: {
// ein Beispiel für eine dateibasierte Konvention,
// Sie müssen ihr nicht folgen
include: [
'tests/browser/**/*.{test,spec}.ts',
'tests/**/*.browser.{test,spec}.ts',
],
name: 'browser',
browser: {
enabled: true,
name: 'chrome',
},
},
},
]);Anbieter-Konfiguration
:::tabs key:provider == Playwright Sie können konfigurieren, wie Vitest den Browser startet und den Seitenkontext mithilfe des Feldes providerOptions erstellt:
export default defineConfig({
test: {
browser: {
providerOptions: {
launch: {
devtools: true,
},
context: {
geolocation: {
latitude: 45,
longitude: -30,
},
reducedMotion: 'reduce',
},
},
},
},
});Um Typhinweise zu erhalten, fügen Sie @vitest/browser/providers/playwright zu compilerOptions.types in Ihrer tsconfig.json-Datei hinzu. == WebdriverIO Sie können konfigurieren, welche Optionen Vitest beim Starten eines Browsers mithilfe des Feldes providerOptions verwenden soll:
export default defineConfig({
test: {
browser: {
browser: 'chrome',
providerOptions: {
region: 'eu',
capabilities: {
browserVersion: '27.0',
platformName: 'Windows 10',
},
},
},
},
});Um Typhinweise zu erhalten, fügen Sie @vitest/browser/providers/webdriverio zu compilerOptions.types in Ihrer tsconfig.json-Datei hinzu. :::
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
Browser-Kompatibilität
Vitest verwendet den Vite Dev Server, um Ihre Tests auszuführen. Daher unterstützen wir nur Funktionen, die in der Option esbuild.target (standardmäßig esnext) definiert sind.
Standardmäßig zielt Vite auf Browser ab, die native ES Modules, nativen ESM Dynamic Import und import.meta unterstützen. Zusätzlich verwenden wir BroadcastChannel zur Kommunikation zwischen Iframes:
- Chrome >=87
- Firefox >=78
- Safari >=15.4
- Edge >=88
Tests ausführen
Wenn Sie einen Browser-Namen in der Browser-Option angeben, versucht Vitest standardmäßig, den angegebenen Browser über preview zu starten und die Tests 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 --browser-Flag, gefolgt vom Browser-Namen, wie folgt:
npx vitest --browser=chromeOder Sie können Browser-Optionen in Punktnotation an die CLI übergeben:
npx vitest --browser.name=chrome --browser.headlessStandardmäßig öffnet Vitest automatisch die Browser-Benutzeroberfläche zur Entwicklung. Ihre Tests werden in einem Iframe im Zentrum ausgeführt. Sie können den Viewport konfigurieren, indem Sie die gewünschten Dimensionen auswählen, page.viewport innerhalb des Tests aufrufen oder Standardwerte in der Konfiguration festlegen.
Headless-Modus
Der Headless-Modus ist eine weitere im Browser-Modus verfügbare Option. Im Headless-Modus läuft der Browser im Hintergrund ohne Benutzeroberfläche, was ihn besonders nützlich für die Ausführung automatisierter Tests macht. Die Headless-Option in Vitest kann auf einen booleschen Wert eingestellt werden, um den Headless-Modus zu aktivieren oder zu deaktivieren.
Im Headless-Modus öffnet Vitest die Benutzeroberfläche nicht automatisch. Wenn Sie die Benutzeroberfläche weiterhin verwenden möchten, aber die Tests im Headless-Modus laufen sollen, können Sie das Paket @vitest/ui installieren und das --ui-Flag beim Ausführen von Vitest übergeben.
Hier ist ein Beispiel für eine Konfiguration, die den Headless-Modus aktiviert:
export default defineConfig({
test: {
browser: {
provider: 'playwright',
enabled: true,
headless: true,
},
},
});Sie können den Headless-Modus auch über das --browser.headless-Flag in der CLI einstellen, wie folgt:
npx vitest --browser.name=chrome --browser.headlessIn diesem Fall wird Vitest im Headless-Modus unter Verwendung des Chrome-Browsers 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
Vitest bietet sofort einsatzbereite Pakete zum Rendern von Komponenten für mehrere beliebte Frameworks:
vitest-browser-vuezum Rendern von Vue-Komponentenvitest-browser-sveltezum Rendern von Svelte-Komponentenvitest-browser-reactzum Rendern von React-Komponenten
Wenn Ihr Framework nicht aufgeführt ist, 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 auf dieser Seite dazu hinzufügen. Stellen Sie sicher, dass es einen Namen hat, der mit vitest-browser- beginnt.
Neben dem Rendern von Komponenten und dem Lokalisieren von Elementen müssen Sie auch Zusicherungen (Assertions) durchführen. Vitest bündelt die Bibliothek @testing-library/jest-dom, um eine breite Palette von DOM-Assertions standardmäßig bereitzustellen. Lesen Sie mehr in 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 Reihe nützlicher Dienstprogramme für Ihre Tests zur Verfügung. Wenn Sie beispielsweise eine Interaktion durchführen müssen, wie das Klicken auf ein Element oder die Eingabe von Text in ein Eingabefeld, können Sie userEvent von @vitest/browser/context verwenden. Lesen Sie mehr in 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);
// Asserts initial state.
await expect
.element(screen.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Get the input DOM node by querying the associated label.
const usernameInput = screen.getByLabelText(/username/i);
// Type the name into the input. This already validates that the input
// is filled correctly, no need to check the value manually.
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 () => {
// Render a React element into the DOM
const screen = render(<Fetch url="/greeting" />);
await screen.getByText('Load Greeting').click();
// wait before throwing an error if it cannot find an element
const heading = screen.getByRole('heading');
// assert that the alert message is correct
await expect.element(heading).toHaveTextContent('hello there');
await expect.element(screen.getByRole('button')).toBeDisabled();
});Vitest unterstützt nicht alle Frameworks standardmäßig, aber Sie können externe Tools verwenden, um Tests mit diesen Frameworks auszuführen. Wir ermutigen die Community auch, eigene vitest-browser-Wrapper zu entwickeln – 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:
@testing-library/preactzum Rendern von Preact-Komponenten@solidjs/testing-libraryzum Rendern von Solid-Komponenten@marko/testing-libraryzum Rendern von Marko-Komponenten
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 aus @vitest/browser/context, das unter der Haube das Chrome DevTools Protocol oder Webdriver (je nach Anbieter) verwendet.
// based on @testing-library/preact example
// 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() will return the element or null if it cannot be found.
// .element() will return the element or throw an error if it cannot be found.
expect(screen.getByText(testMessage).query()).not.toBeInTheDocument();
// The queries can accept a regex to make your selectors more
// resilient to content tweaks and changes.
await screen.getByLabelText(/show/i).click();
await expect.element(screen.getByText(testMessage)).toBeInTheDocument();
});// based on @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.element(screen.getByText('Id: 1234')).toBeInTheDocument();
});// based on @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>
`);
});Einschränkungen
Thread-blockierende Dialoge
Bei der Verwendung von Vitest Browser ist es wichtig zu beachten, dass Dialoge, die den Thread blockieren, wie alert oder confirm, nicht nativ verwendet werden können. Dies liegt daran, dass sie die Webseite blockieren. Dadurch kann Vitest die Kommunikation mit der Seite nicht fortsetzen, was zum Hängenbleiben der Ausführung führt.
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 Popup-Web-APIs verwendet. Es wird jedoch weiterhin empfohlen, diese Web-APIs für eine bessere Nutzererfahrung zu mocken. Lesen Sie mehr unter Mocking.