Buns Test-Runner funktioniert gut mit bestehenden Komponenten- und DOM-Testing-Bibliotheken, einschließlich React Testing Library und happy-dom.
happy-dom
Für das Schreiben von Headless-Tests für Ihren Frontend-Code und Komponenten empfehlen wir happy-dom. Happy DOM implementiert einen vollständigen Satz von HTML- und DOM-APIs in reinem JavaScript und ermöglicht es, eine Browserumgebung mit hoher Wiedergabetreue zu simulieren.
Um zu beginnen, installieren Sie das @happy-dom/global-registrator-Paket als dev-Abhängigkeit.
bun add -d @happy-dom/global-registratorWir verwenden Buns Preload-Funktionalität, um die happy-dom-Globals vor dem Ausführen unserer Tests zu registrieren. Dieser Schritt macht Browser-APIs wie document im globalen Geltungsbereich verfügbar. Erstellen Sie eine Datei namens happydom.ts im Root Ihres Projekts und fügen Sie den folgenden Code hinzu:
import { GlobalRegistrator } from "@happy-dom/global-registrator";
GlobalRegistrator.register();Um diese Datei vor bun test zu preladen, öffnen oder erstellen Sie eine bunfig.toml-Datei und fügen Sie die folgenden Zeilen hinzu.
[test]
preload = ["./happydom.ts"]Dies führt happydom.ts aus, wenn Sie bun test ausführen. Jetzt können Sie Tests schreiben, die Browser-APIs wie document und window verwenden.
import { test, expect } from "bun:test";
test("DOM-Test", () => {
document.body.innerHTML = `<button>Mein Button</button>`;
const button = document.querySelector("button");
expect(button?.innerText).toEqual("Mein Button");
});TypeScript-Unterstützung
Abhängig von Ihrer tsconfig.json-Einrichtung können Sie einen "Cannot find name 'document'"-Typfehler im obigen Code sehen. Um die Typen für document und andere Browser-APIs zu "injizieren", fügen Sie die folgende Triple-Slash-Direktive oben in jede Testdatei hinzu.
/// <reference lib="dom" />
import { test, expect } from "bun:test";
test("DOM-Test", () => {
document.body.innerHTML = `<button>Mein Button</button>`;
const button = document.querySelector("button");
expect(button?.innerText).toEqual("Mein Button");
});Lassen Sie uns diesen Test mit bun test ausführen:
bun testbun test v1.3.3
dom.test.ts:
✓ DOM-Test [0.82ms]
1 bestanden
0 fehlgeschlagen
1 expect()-Aufrufe
1 Test über 1 Datei ausgeführt. 1 insgesamt [125.00ms]React Testing Library
Bun funktioniert nahtlos mit React Testing Library zum Testen von React-Komponenten. Nach dem Einrichten von happy-dom wie oben gezeigt, können Sie React Testing Library normal installieren und verwenden.
bun add -d @testing-library/react @testing-library/jest-dom/// <reference lib="dom" />
import { test, expect } from 'bun:test';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
function Button({ children }: { children: React.ReactNode }) {
return <button>{children}</button>;
}
test('rendert Button', () => {
render(<Button>Klick mich</Button>);
expect(screen.getByRole('button')).toHaveTextContent('Klick mich');
});Fortgeschrittenes DOM-Testing
Custom Elements
Sie können Custom Elements und Web Components mit demselben Setup testen:
/// <reference lib="dom" />
import { test, expect } from "bun:test";
test("Custom Element", () => {
// Ein Custom Element definieren
class MyElement extends HTMLElement {
constructor() {
super();
this.innerHTML = "<p>Inhalt des Custom Elements</p>";
}
}
customElements.define("my-element", MyElement);
// In Tests verwenden
document.body.innerHTML = "<my-element></my-element>";
const element = document.querySelector("my-element");
expect(element?.innerHTML).toBe("<p>Inhalt des Custom Elements</p>");
});Event-Testing
Testen Sie DOM-Events und Benutzerinteraktionen:
/// <reference lib="dom" />
import { test, expect } from "bun:test";
test("Button-Klick-Event", () => {
let geklickt = false;
document.body.innerHTML = '<button id="test-btn">Klick mich</button>';
const button = document.getElementById("test-btn");
button?.addEventListener("click", () => {
geklickt = true;
});
button?.click();
expect(geklickt).toBe(true);
});Konfigurationstipps
Globales Setup
Für komplexere DOM-Testing-Setups können Sie eine umfassendere Preload-Datei erstellen:
import { GlobalRegistrator } from "@happy-dom/global-registrator";
import "@testing-library/jest-dom";
// happy-dom globals registrieren
GlobalRegistrator.register();
// Fügen Sie hier globale Testkonfiguration hinzu
global.ResizeObserver = class ResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
};
// Andere APIs nach Bedarf mocken
Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});Aktualisieren Sie dann Ihre bunfig.toml:
[test]
preload = ["./test-setup.ts"]Fehlerbehebung
Häufige Probleme
TypeScript-Fehler für DOM-APIs: Stellen Sie sicher, dass Sie die /// <reference lib="dom" />-Direktive oben in Ihren Testdateien einfügen.
Fehlende Globals: Stellen Sie sicher, dass @happy-dom/global-registrator korrekt in Ihrer Preload-Datei importiert und registriert ist.
Probleme beim Rendern von React-Komponenten: Stellen Sie sicher, dass Sie sowohl @testing-library/react installiert als auch happy-dom korrekt eingerichtet haben.
Performance-Überlegungen
Happy-dom ist schnell, aber für sehr große Testsuiten möchten Sie vielleicht:
beforeEachverwenden, um den DOM-Zustand zwischen Tests zurückzusetzen- Vermeiden, zu viele DOM-Elemente in einem einzelnen Test zu erstellen
cleanup-Funktionen von Testing-Bibliotheken in Betracht ziehen
import { afterEach } from "bun:test";
import { cleanup } from "@testing-library/react";
afterEach(() => {
cleanup();
document.body.innerHTML = "";
});Vue Testing Library
Bun funktioniert auch mit Vue Testing Library:
bun add -d @testing-library/vue @vue/test-utils/// <reference lib="dom" />
import { test, expect } from "bun:test";
import { render, screen } from "@testing-library/vue";
import MyComponent from "./MyComponent.vue";
test("rendert Vue-Komponente", () => {
render(MyComponent, {
props: {
title: "Test Titel"
}
});
expect(screen.getByText("Test Titel")).toBeInTheDocument();
});Svelte Testing
Für Svelte-Komponenten können Sie @testing-library/svelte verwenden:
bun add -d @testing-library/svelte/// <reference lib="dom" />
import { test, expect } from "bun:test";
import { render, screen } from "@testing-library/svelte";
import MyComponent from "./MyComponent.svelte";
test("rendert Svelte-Komponente", () => {
render(MyComponent, {
props: {
name: "Test Benutzer"
}
});
expect(screen.getByText("Hallo Test Benutzer")).toBeInTheDocument();
});Best Practices
DOM-Zustand isolieren
Stellen Sie sicher, dass jeder Test mit einem sauberen DOM-Zustand beginnt:
import { afterEach } from "bun:test";
afterEach(() => {
document.body.innerHTML = "";
document.head.innerHTML = "";
});Asynchrone Updates handhaben
Verwenden Sie waitFor für asynchrone DOM-Updates:
import { test, expect } from "bun:test";
import { waitFor } from "@testing-library/react";
test("wartet auf DOM-Update", async () => {
render(<AsyncComponent />);
// Warten, bis der Inhalt geladen ist
const content = await waitFor(() => screen.getByText("Geladen"));
expect(content).toBeInTheDocument();
});Accessibility-Tests
Verwenden Sie Testing Librarys Accessibility-Funktionen:
import { test, expect } from "bun:test";
import { render, screen } from "@testing-library/react";
test("Barrierefreiheit", () => {
render(<Button aria-label="Menü schließen">X</Button>);
// Nach accessiblem Namen suchen
expect(screen.getByLabelText("Menü schließen")).toBeInTheDocument();
// Rolle überprüfen
expect(screen.getByRole("button")).toBeInTheDocument();
});