Controllare la validità dell’HTML con i test automatizzati nel flusso di sviluppo

by Anastasia P.
SHARE
Controllare la validità dell’HTML con i test automatizzati nel flusso di sviluppo
© Guida-HTML5.it

Introduzione

Quando si parla di validazione HTML, spesso si pensa solo ai validatori online. In realtà, per un progetto moderno è molto utile integrare la verifica del markup direttamente nel processo di sviluppo, così da intercettare gli errori prima che arrivino in produzione. Un approccio pratico e molto efficace è usare test automatizzati locali che controllano la struttura HTML generata dall’applicazione o da una pagina statica.

Questo tutorial ti mostra un sotto-argomento utile e concreto: validare l’HTML con test automatizzati basati su Node.js e jsdom. È una soluzione ideale quando vuoi verificare che una pagina contenga elementi obbligatori, attributi corretti, gerarchie valide e contenuti coerenti. Non sostituisce un validatore semantico completo, ma è perfetta per bloccare regressioni nei progetti reali.

Immagina, ad esempio, di lavorare su una landing page o su un componente riutilizzabile. Un piccolo errore, come un id duplicato, un input senza label o un titolo mancante, può passare inosservato. Con un test automatico, invece, puoi far fallire la build appena il problema compare.

Codice completo

Nel seguente esempio useremo:

  • Node.js per eseguire i test in locale
  • jsdom per simulare il DOM di una pagina HTML
  • Vitest come test runner moderno e semplice da usare

Struttura minima del progetto:

progetto/
├─ index.html
├─ src/
│  └─ page.js
├─ tests/
│  └─ html.test.js
├─ package.json

1) Pagina HTML di esempio

<!-- index.html -->
<!DOCTYPE html>
<html lang="it">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Pagina prodotto</title>
  </head>
  <body>
    <main>
      <h1>Cuffie wireless Pro Sound</h1>
      <p>Audio nitido, autonomia lunga e design leggero.</p>

      <section aria-labelledby="features-title">
        <h2 id="features-title">Caratteristiche</h2>
        <ul>
          <li>Bluetooth 5.3</li>
          <li>Autonomia fino a 30 ore</li>
          <li>Ricarica rapida USB-C</li>
        </ul>
      </section>

      <form id="newsletter-form">
        <label for="email">Email</label>
        <input id="email" name="email" type="email" />
        <button type="submit">Iscriviti</button>
      </form>
    </main>
  </body>
</html>

2) Installazione delle dipendenze

npm init -y
npm install -D vitest jsdom

3) Test HTML automatico

// tests/html.test.js
import { describe, it, expect } from "vitest";
import fs from "node:fs";
import { JSDOM } from "jsdom";

describe("Validazione HTML della pagina prodotto", () => {
  it("deve contenere un titolo principale", () => {
    const html = fs.readFileSync("index.html", "utf-8");
    const dom = new JSDOM(html);
    const h1 = dom.window.document.querySelector("h1");

    expect(h1).not.toBeNull();
    expect(h1.textContent.trim()).toBe("Cuffie wireless Pro Sound");
  });

  it("deve avere un lang corretto nella radice", () => {
    const html = fs.readFileSync("index.html", "utf-8");
    const dom = new JSDOM(html);
    const htmlElement = dom.window.document.documentElement;

    expect(htmlElement.getAttribute("lang")).toBe("it");
  });

  it("deve avere una label associata al campo email", () => {
    const html = fs.readFileSync("index.html", "utf-8");
    const dom = new JSDOM(html);

    const input = dom.window.document.querySelector("#email");
    const label = dom.window.document.querySelector(´label[for="email"]´);

    expect(input).not.toBeNull();
    expect(label).not.toBeNull();
    expect(label.textContent.trim()).toBe("Email");
  });

  it("deve avere una sezione con heading collegato via aria-labelledby", () => {
    const html = fs.readFileSync("index.html", "utf-8");
    const dom = new JSDOM(html);

    const section = dom.window.document.querySelector("section");
    const heading = dom.window.document.querySelector("#features-title");

    expect(section).not.toBeNull();
    expect(heading).not.toBeNull();
    expect(section.getAttribute("aria-labelledby")).toBe("features-title");
  });
});

4) Script nel package.json

{
  "name": "progetto",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "test": "vitest run"
  },
  "devDependencies": {
    "jsdom": "^24.0.0",
    "vitest": "^2.0.0"
  }
}

Per lanciare i test:

npm test

Spiegazione

Il principio è semplice: invece di limitarti a “guardare” il file HTML, lo carichi in un DOM virtuale e fai controlli precisi con asserzioni. Questo è molto utile quando l’HTML viene generato da template, componenti o script lato client.

Perché usare jsdom

jsdom riproduce abbastanza bene il comportamento del browser per operazioni sul DOM. Non è un browser completo, ma per testare markup e struttura è più che sufficiente. Puoi verificare:

  • presenza di elementi fondamentali come main, h1, form
  • attributi corretti come lang, aria-label, for
  • relazioni tra elementi, ad esempio label e input
  • assenza di regressioni in componenti critici

Che cosa stai davvero validando

Questa tecnica non sostituisce un validatore HTML “formale”, ma controlla aspetti molto utili dal punto di vista pratico:

  • coerenza strutturale: il documento ha i nodi essenziali?
  • accessibilità di base: i controlli hanno label e riferimenti corretti?
  • contenuto atteso: il titolo o il testo chiave sono presenti?
  • regressioni: una modifica ha rotto la struttura della pagina?

Esempio di caso reale

Supponiamo che un collega modifichi il template e rimuova per errore il for="email" dalla label. La pagina potrebbe sembrare ancora funzionante, ma l’input non sarebbe più associato correttamente alla sua etichetta. Il test fallirebbe subito, segnalando il problema prima del deploy.

Best practice

  • Testa i requisiti importanti, non ogni singolo tag: concentrati su ciò che conta davvero per UX, accessibilità e struttura.
  • Usa nomi di test chiari: devono descrivere il comportamento atteso in modo leggibile.
  • Verifica gli attributi semantici: lang, alt, aria-labelledby, for, type.
  • Non affidarti solo ai test DOM: affianca sempre controlli manuali e, quando serve, un validatore HTML completo.
  • Integra i test nella CI: così ogni commit viene controllato automaticamente.
  • Evita test fragili: non basarti troppo su dettagli estetici o su testi che cambiano spesso senza motivo.

Un buon approccio è combinare test strutturali e test di contenuto. Ad esempio, puoi verificare che una pagina abbia un h1 e che il form di contatto contenga almeno un campo obbligatorio. In questo modo i test restano utili, ma non diventano eccessivamente rigidi.

Riepilogo

Validare l’HTML con test automatizzati locali è una strategia pratica e molto efficace per mantenere alta la qualità del markup. Con strumenti come Vitest e jsdom puoi controllare la struttura delle pagine, verificare attributi importanti e prevenire errori introdotti durante lo sviluppo.

  • Carichi l’HTML in un DOM virtuale
  • Scrivi asserzioni su elementi e attributi
  • Blocchi regressioni prima che arrivino in produzione
  • Rendi il controllo parte del flusso di sviluppo

È una soluzione particolarmente adatta a progetti con template statici, componenti UI e pagine generate dinamicamente. Se la usi insieme a un validatore HTML classico, ottieni un processo di qualità molto più solido.

Approfondisci con risorse ufficiali

  • Vitest: documentazione ufficiale del test runner
  • jsdom: repository e guida ufficiale
  • MDN Web Docs: riferimento su struttura HTML, attributi globali e accessibilità
  • WHATWG HTML Living Standard: specifica ufficiale del linguaggio HTML
  • WAI-ARIA Authoring Practices: linee guida per markup accessibile

SHARE