Skip to content

Il test runner di Bun funziona bene con le librerie esistenti per i test di componenti e DOM, incluse React Testing Library e happy-dom.

happy-dom

Per scrivere test headless per il tuo codice frontend e componenti, raccomandiamo happy-dom. Happy DOM implementa un insieme completo di API HTML e DOM in JavaScript puro, rendendo possibile simulare un ambiente browser con alta fedelta.

Per iniziare, installa il pacchetto @happy-dom/global-registrator come dipendenza di sviluppo.

bash
bun add -d @happy-dom/global-registrator

Utilizzeremo la funzionalita di preload di Bun per registrare i globali di happy-dom prima di eseguire i nostri test. Questo passaggio rendera disponibili le API del browser come document nel scope globale. Crea un file chiamato happydom.ts nella root del tuo progetto e aggiungi il seguente codice:

happydom.ts
ts
import { GlobalRegistrator } from "@happy-dom/global-registrator";

GlobalRegistrator.register();

Per preloadare questo file prima di bun test, apri o crea un file bunfig.toml e aggiungi le seguenti righe.

bunfig.toml
toml
[test]
preload = ["./happydom.ts"]

Questo eseguira happydom.ts quando esegui bun test. Ora puoi scrivere test che usano le API del browser come document e window.

dom.test.ts
ts
import { test, expect } from "bun:test";

test("test dom", () => {
  document.body.innerHTML = `<button>My button</button>`;
  const button = document.querySelector("button");
  expect(button?.innerText).toEqual("My button");
});

Supporto TypeScript

A seconda della tua configurazione tsconfig.json, potresti vedere un errore di tipo "Cannot find name 'document'" nel codice sopra. Per "iniettare" i tipi per document e altre API del browser, aggiungi la seguente direttiva triple-slash in cima a qualsiasi file di test.

dom.test.ts
ts
/// <reference lib="dom" />

import { test, expect } from "bun:test";

test("test dom", () => {
  document.body.innerHTML = `<button>My button</button>`;
  const button = document.querySelector("button");
  expect(button?.innerText).toEqual("My button");
});

Eseguiamo questo test con bun test:

bash
bun test
bun test v1.3.3

dom.test.ts:
✓ test dom [0.82ms]

 1 pass
 0 fail
 1 expect() calls
Ran 1 tests across 1 files. 1 total [125.00ms]

React Testing Library

Bun funziona perfettamente con React Testing Library per testare i componenti React. Dopo aver impostato happy-dom come mostrato sopra, puoi installare e usare React Testing Library normalmente.

bash
bun add -d @testing-library/react @testing-library/jest-dom
component.test.tsx
ts
/// <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('renderizza il bottone', () => {
  render(<Button>Click me</Button>);
  expect(screen.getByRole('button')).toHaveTextContent('Click me');
});

Test DOM Avanzati

Elementi Personalizzati

Puoi testare elementi personalizzati e web component usando la stessa configurazione:

custom-element.test.ts
ts
/// <reference lib="dom" />

import { test, expect } from "bun:test";

test("elemento personalizzato", () => {
  // Definisci un elemento personalizzato
  class MyElement extends HTMLElement {
    constructor() {
      super();
      this.innerHTML = "<p>Contenuto elemento personalizzato</p>";
    }
  }

  customElements.define("my-element", MyElement);

  // Usalo nei test
  document.body.innerHTML = "<my-element></my-element>";
  const element = document.querySelector("my-element");
  expect(element?.innerHTML).toBe("<p>Contenuto elemento personalizzato</p>");
});

Test degli Eventi

Testa gli eventi DOM e le interazioni dell'utente:

events.test.ts
ts
/// <reference lib="dom" />

import { test, expect } from "bun:test";

test("evento click del bottone", () => {
  let clicked = false;

  document.body.innerHTML = '<button id="test-btn">Click me</button>';
  const button = document.getElementById("test-btn");

  button?.addEventListener("click", () => {
    clicked = true;
  });

  button?.click();
  expect(clicked).toBe(true);
});

Suggerimenti di Configurazione

Setup Globale

Per configurazioni di test DOM piu complesse, puoi creare un file di preload piu completo:

test-setup.ts
ts
import { GlobalRegistrator } from "@happy-dom/global-registrator";
import "@testing-library/jest-dom";

// Registra i globali di happy-dom
GlobalRegistrator.register();

// Aggiungi qualsiasi configurazione globale di test qui
global.ResizeObserver = class ResizeObserver {
  observe() {}
  unobserve() {}
  disconnect() {}
};

// Mock di altre API come necessario
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(),
  })),
});

Poi aggiorna il tuo bunfig.toml:

bunfig.toml
toml
[test]
preload = ["./test-setup.ts"]

Risoluzione dei Problemi

Problemi Comuni

Errori TypeScript per le API DOM: Assicurati di includere la direttiva /// <reference lib="dom" /> in cima ai tuoi file di test.

Globali mancanti: Assicurati che @happy-dom/global-registrator sia correttamente importato e registrato nel tuo file di preload.

Problemi di rendering dei componenti React: Assicurati di aver installato sia @testing-library/react e di aver configurato correttamente happy-dom.

Considerazioni sulle Performance

Happy-dom e veloce, ma per suite di test molto grandi, potresti voler:

  • Usare beforeEach per resettare lo stato del DOM tra i test
  • Evitare di creare troppi elementi DOM in un singolo test
  • Considerare l'uso delle funzioni cleanup delle librerie di test
test-setup.ts
ts
import { afterEach } from "bun:test";
import { cleanup } from "@testing-library/react";

afterEach(() => {
  cleanup();
  document.body.innerHTML = "";
});

Bun a cura di www.bunjs.com.cn