La pirámide de pruebas de NextPDF
Spec: ISO/IEC/IEEE 29119-4ISO/IEC/IEEE 29119-4Spec: ISO/IEC 25010ISO/IEC 25010PHPStan: Level 10
En resumen
Sección titulada «En resumen»NextPDF no se apoya en un único tipo de prueba. Usa cinco niveles, y cada uno responde a una pregunta distinta sobre el motor. La razón es que un PDF puede pasar una prueba unitaria y, aun así, ser un archivo estructuralmente roto en disco. Esta página nombra los cinco niveles y explica qué debe demostrar cada uno.
Por qué esto importa
Sección titulada «Por qué esto importa»Un motor PDF tiene una superficie de fallo inusualmente amplia. La misma ruta de ejecución puede ser correcta como función y como flujo de bytes, y aun así producir un archivo que un lector conforme rechaza. También puede producir un archivo que se representa de forma sutilmente incorrecta solo en un salto de página. Si se prueba el motor con una única granularidad, solo se obtiene confianza en esa granularidad y en nada más.
La literatura normativa es clara al respecto. Las técnicas de diseño de pruebas basadas en la especificación y las basadas en la estructura no guardan relación entre sí, y se recomienda que una estrategia de pruebas use más de un criterio, con al menos uno funcional y uno estructural (ISO/IEC/IEEE 29119-4, Anexo A). Un único nivel no es una versión reducida de una buena estrategia. Es una estrategia distinta y, además, incompleta.
La versión breve
Sección titulada «La versión breve»Las pruebas de NextPDF se organizan en cinco niveles, de la base al vértice:
- Unitario — una clase o función, de forma aislada. La base amplia.
- Integración — unidades que colaboran a través de un límite de módulo.
- Estructural — el grafo de objetos del PDF emitido, la tabla de referencias cruzadas y el tráiler están bien formados y son conformes.
- Visual — la página representada coincide con una referencia aprobada dentro de una tolerancia declarada.
- De referencia (golden) — fixtures de extremo a extremo ancladas que detectan desviaciones no deseadas en la salida final. El vértice.
Cada nivel demuestra algo que el nivel inferior no puede. Ninguno es decorativo. La forma de pirámide tiene que ver con la cantidad —muchas pruebas unitarias baratas, menos pruebas de extremo a extremo costosas—, no con la importancia.
Cómo lo aborda NextPDF
Sección titulada «Cómo lo aborda NextPDF»Los niveles son concretos, no aspiracionales. La configuración de PHPUnit del repositorio declara cada uno como un conjunto de pruebas con nombre asignado uno a uno a un directorio. Por tanto, un nivel es una ubicación a la que se puede apuntar un ejecutor, no una etiqueta en una diapositiva. Entre los conjuntos de pruebas que reconocería un ingeniero veterano están Unit, Integration, Golden, Snapshot, Reproducibility, Conformance, Standards y Performance, cada uno con su propio perfil de ejecución (aislamiento, presupuesto de tiempo y si se ejecuta de forma predeterminada en la integración continua).
Esa separación es deliberada. El nivel base rápido (Unit) se ejecuta en cada cambio con un presupuesto de un segundo por prueba. Los niveles más lentos y sensibles al entorno —representación visual, conformidad completa, rendimiento— son opcionales o nocturnos. Esto mantiene la ruta habitual rápida y determinista sin renunciar a las comprobaciones más profundas. El tipado estricto sostiene toda la pila. El análisis del motor se ejecuta en Spec: PHPStan, Level 10PHPStan Level 10 con el presupuesto de errores fijado en cero, de modo que una amplia clase de defectos ni siquiera llega a una prueba.
- Tier 1 of 5UnitIsolated behaviour of a single class or function; the broad base.
- Tier 2 of 5IntegrationCollaborating units across a module boundary.
- Tier 3 of 5StructuralThe emitted PDF object/xref structure is well-formed and conformant.
- Tier 4 of 5VisualRendered output matches an approved reference within tolerance.
- Tier 5 of 5GoldenEnd-to-end byte/lossless fixtures pinned as the contract; the apex.
Ejemplo práctico
Sección titulada «Ejemplo práctico»Los niveles son accesibles desde los propios scripts del motor. Un cambio en un solo formateador se comprueba en la base. Un cambio en la fachada del documento se comprueba en varios niveles:
<?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.El objetivo del ejemplo es la lógica de enrutamiento, no los comandos. El nivel que se ejercita lo determina lo que el cambio puede romper. La infraestructura convierte cada nivel en un objetivo de primera clase, ejecutable por separado.
Idea errónea habitual
Sección titulada «Idea errónea habitual»A menudo la pirámide se interpreta como una clasificación: las pruebas unitarias abajo porque importan menos, las de extremo a extremo arriba porque importan más (o al revés). No es ni lo uno ni lo otro. El eje vertical es, a grandes rasgos, coste y cantidad: muchas pruebas unitarias rápidas y baratas que forman una base amplia; por encima, pruebas progresivamente menos numerosas, más lentas y de mayor fidelidad. Una prueba de referencia (golden) no es «mejor» que una prueba unitaria. Detecta un fallo distinto, más tarde, de forma más costosa, y sería un mal sustituto de las miles de comprobaciones rápidas situadas debajo.
La segunda idea errónea es que un número de cobertura alto significa que la pirámide es sólida. No lo significa. La cobertura mide ejecución, no detección. Las normas no equiparan explícitamente el orden de cobertura con la capacidad de encontrar fallos. Las pruebas de mutación existen precisamente para exponer esa brecha.
Límites y fronteras
Sección titulada «Límites y fronteras»Esta página describe la forma y el propósito de la estrategia, no sus resultados actuales. Los recuentos de pruebas, los porcentajes de cobertura y las puntuaciones de mutación están deliberadamente ausentes aquí. Son señales de calidad dinámicas, generadas a partir de artefactos de integración continua. Las cifras actuales se publican con cada compilación. Congeladas en prosa, quedarían silenciosamente desactualizadas. El único número que se indica —PHPStan Level 10— es un dato de configuración estable, verificable en la configuración de análisis estático del motor, no una medición.
Los nombres de los niveles son vocabulario de arquitectura estable. El conjunto preciso de suites y sus perfiles de ejecución evoluciona con el motor y pertenece a la configuración de pruebas, que es la autoridad si alguna vez difiere de esta explicación. Esta página no afirma ninguna tasa de aprobación concreta ni establece comparación alguna con la estrategia de pruebas de ninguna otra biblioteca.
Documentación relacionada
Sección titulada «Documentación relacionada»- Pruebas de archivos de referencia (golden) — cómo el nivel del vértice ancla la salida de referencia y conserva su integridad.
- Las pruebas de mutación, explicadas — por qué un número de cobertura no demuestra que las pruebas de estos niveles funcionen realmente.
- Tipos estrictos, en todas partes — cómo PHPStan Level 10 elimina una clase de defectos antes de que se ejecute cualquier nivel.
Glosario
Sección titulada «Glosario»- Nivel de pruebas — un nivel de la estrategia que demuestra un tipo de propiedad (por ejemplo, comportamiento unitario o validez estructural). NextPDF usa cinco.
- Prueba estructural — una comprobación de que el grafo de objetos del PDF emitido, la tabla de referencias cruzadas y el tráiler están bien formados y son conformes, en lugar de limitarse a comprobar un valor de retorno.
- Prueba visual — una comprobación de que una página representada coincide con una imagen de referencia aprobada dentro de una tolerancia declarada.
- Prueba de referencia (golden) — una comprobación de extremo a extremo contra una salida de referencia anclada que nunca se actualiza de forma automática; el contrato de «la salida no cambió».
- Eficacia de las pruebas — la capacidad de un conjunto de pruebas para exponer fallos, que ISO/IEC/IEEE 29119-4 distingue de la cobertura. Aclaración sobre la sigla: el MSI (Mutation Score Indicator, indicador de puntuación de mutación) se define en la página de pruebas de mutación.
- PHPStan Level 10 — el nivel de análisis estático más estricto; NextPDF lo ejecuta con el presupuesto de errores fijado en cero.