La piramide dei test di NextPDF
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: ISO/IEC 25010 ISO/IEC 25010 Evidence: Test-backed PHPStan: Level 10
In sintesi
Sezione intitolata “In sintesi”NextPDF non si affida a un solo tipo di test. Ne usa cinque livelli, e ciascuno risponde a una domanda diversa sul motore. Il motivo è che un PDF può superare un test unitario ed essere comunque un file strutturalmente danneggiato su disco. Questa pagina presenta i cinque livelli e ciò che ciascuno deve dimostrare.
Perché è importante
Sezione intitolata “Perché è importante”Un motore PDF ha una superficie di errore insolitamente ampia. Lo stesso percorso di codice può risultare corretto come funzione e come flusso di byte, e produrre comunque un file che un lettore conforme rifiuta. Può anche generare un file il cui rendering risulta leggermente errato solo in corrispondenza di un’interruzione di pagina. Se il motore viene testato a una sola granularità, la fiducia ottenuta vale solo per quella granularità, e per nient’altro.
La letteratura sugli standard è chiara su questo punto. Le tecniche di progettazione dei test basate sulla specifica e quelle basate sulla struttura non sono tra loro correlate, e per una strategia di test è consigliato adottare più di un criterio, con almeno uno funzionale e uno strutturale (ISO/IEC/IEEE 29119-4, Annex A). Un singolo livello non è la versione ridotta di una buona strategia: è una strategia diversa, e incompleta.
In breve
Sezione intitolata “In breve”I test di NextPDF sono organizzati in cinque livelli, dalla base all’apice:
- Unitario — una sola classe o funzione, in isolamento. L’ampia base.
- Di integrazione — unità che collaborano attraverso il confine di un modulo.
- Strutturale — il grafo degli oggetti del PDF emesso, la tabella dei riferimenti incrociati e il trailer sono ben formati e conformi.
- Visivo — la pagina sottoposta a rendering corrisponde a un riferimento approvato entro una tolleranza dichiarata.
- Golden — fixture end-to-end ancorate che intercettano scostamenti involontari nell’output finale. L’apice.
Ogni livello dimostra qualcosa che quello sottostante non può dimostrare. Nessuno di essi è decorativo. La forma a piramide riguarda la quantità — molti test unitari economici, meno test end-to-end costosi — non l’importanza.
Come NextPDF lo affronta
Sezione intitolata “Come NextPDF lo affronta”I livelli sono concreti, non aspirazionali. La configurazione PHPUnit del repository li dichiara come suite di test denominate, mappate una a una su una directory. Un livello è quindi un target a cui indirizzare un runner, non un’etichetta in una slide. Le suite che un ingegnere esperto riconoscerà includono Unit, Integration, Golden, Snapshot, Reproducibility, Conformance, Standards e Performance, ciascuna con il proprio profilo di esecuzione (isolamento, budget temporale e inclusione o meno nell’integrazione continua per impostazione predefinita).
Questa separazione è deliberata. Il livello di base veloce (Unit) viene eseguito a ogni modifica con un budget di un secondo per test. I livelli più lenti e sensibili all’ambiente — rendering visivo, conformità completa, prestazioni — sono opzionali o notturni. Questo mantiene il percorso comune veloce e deterministico senza rinunciare ai controlli più approfonditi. La tipizzazione stretta sostiene l’intero stack. Il motore viene analizzato con Spec: PHPStan, Level 10 PHPStan Level 10 , mantenendo il budget di errore bloccato a zero, così che un’ampia classe di difetti non raggiunga mai alcun test.
- Tier 1 of 5 Unit Isolated behaviour of a single class or function; the broad base.
- Tier 2 of 5 Integration Collaborating units across a module boundary.
- Tier 3 of 5 Structural The emitted PDF object/xref structure is well-formed and conformant.
- Tier 4 of 5 Visual Rendered output matches an approved reference within tolerance.
- Tier 5 of 5 Golden End-to-end byte/lossless fixtures pinned as the contract; the apex.
Che cosa dicono le evidenze
Sezione intitolata “Che cosa dicono le evidenze”Evidence: Test-backed Le cinque suite esistono come suite di test PHPUnit dichiarate nella configurazione del motore, ciascuna vincolata alla propria directory e al proprio profilo di esecuzione. Il vocabolario dei livelli usato in questa pagina è lo stesso usato dall’infrastruttura di test.
Evidence: Standard-backed Il motivo per cui serve più di un livello è fondato su Spec: ISO/IEC/IEEE 29119-4, Annex A ISO/IEC/IEEE 29119-4 Annex A : i criteri di copertura non sono tutti correlati tra loro, ed è consigliato che una strategia combini tecniche funzionali e strutturali. Aspetto cruciale: lo stesso allegato osserva che l’ordinamento per sussunzione tra i criteri di copertura non dice nulla sulla loro capacità di esporre i guasti — l’efficacia dei test (ISO/IEC/IEEE 29119-4, §C.2.4). «Più copertura» non equivale a «test migliori».
Evidence: Standard-backed La scelta di quali proprietà dimostrare corrisponde alle caratteristiche di qualità del prodotto di Spec: ISO/IEC 25010 ISO/IEC 25010 : correttezza funzionale (unitario, integrazione) e le proprietà a livello di file che rendono un PDF effettivamente utilizzabile a valle (strutturale, visivo, golden). Il modello di qualità chiarisce esplicitamente che caratteristiche diverse contano in contesti d’uso diversi.
Esempio pratico
Sezione intitolata “Esempio pratico”I livelli sono indirizzabili dagli stessi script del motore. Una modifica a un singolo formatter viene verificata alla base. Una modifica alla facciata del documento viene verificata attraverso più livelli:
<?php
declare(strict_types=1);
// Tier 1 — Unit: one unit, isolated, fast.// composer test:unit → phpunit --testsuite Unit
// Tier 2 — Integration: collaborating units across a boundary.// composer test:integration → phpunit --testsuite Integration
// Tier 3 — Structural: the emitted PDF object graph is well-formed.// vendor/bin/phpunit --testsuite Conformance
// Tier 4/5 — Visual + Golden: rendered/serialized output vs a pinned// reference (golden is byte/structure-pinned, never auto-updated).// vendor/bin/phpunit --testsuite Golden
// A change to the document facade touches every API, so the routing// guidance escalates it from "unit only" to the full unit + integration// surface — the tier you run is a function of blast radius, not habit.Il punto dell’esempio è la logica di instradamento, non i comandi. Il livello da eseguire si sceglie in base a ciò che la modifica può rompere. L’infrastruttura rende ogni livello un target di prima classe, eseguibile separatamente.
Idea errata comune
Sezione intitolata “Idea errata comune”La piramide viene spesso letta come una classifica — i test unitari in basso perché contano meno, gli end-to-end in alto perché contano di più (o viceversa). Non è né l’una né l’altra cosa. L’asse verticale rappresenta grossomodo costo e quantità: molti test unitari veloci ed economici formano un’ampia base; al di sopra, test progressivamente meno numerosi, più lenti e con maggiore fedeltà. Un test golden non è «migliore» di un test unitario. Intercetta un guasto diverso, più tardi, in modo più costoso, e sarebbe un cattivo sostituto delle migliaia di controlli veloci che lo precedono.
La seconda idea errata è che un numero di copertura elevato significhi che la piramide è solida. Non è così. La copertura misura l’esecuzione, non il rilevamento. Gli standard rifiutano esplicitamente di equiparare l’ordinamento della copertura alla capacità di individuare i guasti. Quella lacuna è esattamente ciò che il mutation testing serve a esporre.
Limiti e confini
Sezione intitolata “Limiti e confini”Questa pagina descrive la forma e l’intento della strategia, non i suoi risultati attuali. Conteggi dei test, percentuali di copertura e punteggi di mutazione sono deliberatamente assenti qui. Sono segnali di qualità dinamici, generati a partire dagli artefatti dell’integrazione continua. Le cifre attuali vengono pubblicate insieme alla build. Se congelate nella prosa, diventerebbero silenziosamente obsolete. L’unico numero indicato — PHPStan Level 10 — è un dato di configurazione stabile, verificabile nella configurazione di analisi statica del motore, non una misurazione.
I nomi dei livelli sono vocabolario architetturale stabile. L’insieme preciso delle suite e i loro profili di esecuzione evolvono con il motore e sono di competenza della configurazione di test, che è l’autorità qualora dovesse mai discordare da questa spiegazione. Questa pagina non afferma alcun tasso di superamento specifico e non fa confronti con la strategia di test di nessun’altra libreria.
Documenti correlati
Sezione intitolata “Documenti correlati”- Test su file golden — come il livello all’apice ancora l’output di riferimento e rimane onesto.
- Il mutation testing, spiegato — perché un numero di copertura non dimostra che i test in questi livelli funzionino davvero.
- Tipi stretti, ovunque — come PHPStan Level 10 rimuove una classe di difetti prima che venga eseguito qualsiasi livello.
Glossario
Sezione intitolata “Glossario”- Livello di test — un livello della strategia che dimostra una specifica proprietà (per esempio, il comportamento unitario o la validità strutturale). NextPDF ne usa cinque.
- Test strutturale — un controllo del fatto che il grafo degli oggetti del PDF emesso, la tabella dei riferimenti incrociati e il trailer siano ben formati e conformi, anziché limitarsi a verificare un valore di ritorno.
- Test visivo — un controllo che una pagina sottoposta a rendering corrisponda a un’immagine di riferimento approvata entro una tolleranza dichiarata.
- Test golden — un controllo end-to-end rispetto a un output di riferimento ancorato che non viene mai aggiornato automaticamente; il contratto per «l’output non è cambiato».
- Efficacia dei test — la capacità di un insieme di test di esporre i guasti, che ISO/IEC/IEEE 29119-4 distingue dalla copertura. Nota sull’acronimo: MSI (Mutation Score Indicator) è definito sulla pagina mutation testing.
- PHPStan Level 10 — il livello di analisi statica più rigoroso; NextPDF lo esegue con il budget di errore bloccato a zero.