Pruebas con archivos de referencia (golden files)
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: ISO/IEC 25010 ISO/IEC 25010 Evidence: Test-backed
En resumen
Sección titulada «En resumen»Un archivo de referencia es un registro del «aspecto que debe tener la salida correcta» contra el que una prueba compara en cada ejecución. NextPDF usa referencias para detectar cambios que nadie pretendía introducir: un flujo comprimido de otra forma, un párrafo que se movió, una coordenada que se desvió. Esta página explica cómo funciona ese proceso y cómo una referencia sigue siendo fiable, en lugar de convertirse en un artefacto obsoleto que nadie lee.
Por qué esto importa
Sección titulada «Por qué esto importa»La generación de PDF es una canalización larga, con muchos puntos en los que puede desviarse en silencio. Una refactorización que «no cambia nada» puede reordenar operadores sin querer, alterar una matriz de transformación o desplazar mínimamente una celda de tabla. Las pruebas unitarias rara vez detectan esto: comprueban un valor que se decidió verificar, no los miles de bytes que no se verificaron. Las técnicas basadas en estructura y en especificación detectan errores distintos, y ninguna cubre por completo a la otra (ISO/IEC/IEEE 29119-4, Annex A). Un archivo de referencia funciona como especificación mediante ejemplo: ancla la salida completa, no una sola aserción.
El riesgo va en ambos sentidos. Una referencia demasiado estricta falla ante cualquier cambio inofensivo y se reaprueba a ciegas hasta que deja de demostrar algo. Una referencia demasiado laxa deja pasar regresiones reales. Encontrar ese equilibrio es la parte difícil del trabajo.
La versión breve
Sección titulada «La versión breve»- Un archivo de referencia es una salida de referencia anclada, generada a partir de un comportamiento del motor reconocido como bueno y registrada en el repositorio.
- Una prueba de referencia vuelve a generar la salida y la compara con la referencia anclada; cualquier diferencia hace fallar la prueba y exige una decisión humana.
- NextPDF compara en el nivel que resulta significativo pero estable: el texto extraído y los operadores estructurales normalizados, no los bytes en bruto, porque los bytes en bruto arrastran ruido (marcas de tiempo, orden de los subconjuntos, compresión) que no constituye una regresión.
- Actualizar una referencia es un acto deliberado y revisado, habilitado mediante el conmutador explícito
GOLDEN_UPDATE; nunca un «aceptar lo que haya cambiado» automático. - Las referencias se diferencian de las pruebas de snapshot y de caracterización en un aspecto decisivo: una referencia nunca se actualiza de forma automática.
Cómo lo aborda NextPDF
Sección titulada «Cómo lo aborda NextPDF»La infraestructura de referencias del motor usa una comparación explícita en dos capas en lugar de una comparación de bytes:
- Generate Render the fixture input through the current engine.
- Layer 1 — text Extract human-readable text from the content stream; diff against the text golden. Catches dropped or reordered content and encoding regressions.
- Layer 2 — structure Extract ordered PDF operators, normalise coordinates to a fixed precision, diff against the operator golden. Catches layout shifts and broken structure.
- Decide Any diff fails the test; a human judges whether it is a regression or an intended change.
Lo que deliberadamente no compara es tan importante como lo que sí compara. La salida en bytes en bruto se excluye porque las marcas de tiempo, el orden de los subconjuntos de fuentes y la compresión de flujos la vuelven frágil sin mejorar su corrección. La comparación de imágenes a nivel de píxel se excluye en este nivel porque necesita un renderizador externo e introduce variabilidad del entorno. Las coordenadas de punto flotante se normalizan a una precisión fija para que el ruido de redondeo sin sentido no se haga pasar por una regresión. Esa es la diferencia entre una referencia que prueba el comportamiento y otra que prueba el ruido ambiental transitorio.
Esta elección también define el perfil de reproducibilidad de la página: estructural. NextPDF documenta tres perfiles: a nivel de bits (se reproducen los bytes exactos), estructural (se reproducen el grafo de objetos y la secuencia de operadores, con variaciones benignas a nivel de byte permitidas) y semántico (se reproduce el significado). Las pruebas de referencia en este nivel afirman por construcción el perfil estructural. Por eso sus referencias sobreviven a una actualización de la biblioteca de compresión, pero aun así fallan ante una tabla desplazada.
Qué dice la evidencia
Sección titulada «Qué dice la evidencia»Evidence: Test-backed La comparación en dos capas (extracción de texto y, a continuación, comparación de operadores estructurales normalizados) es la metodología de referencia documentada del propio motor, y deja la comparación de bytes en bruto, de imágenes y de flotantes exactos explícitamente fuera de alcance por las razones anteriores. El conjunto de referencias es un conjunto de pruebas declarado y ejecutable por separado, distinto de los conjuntos de snapshot y de caracterización.
Evidence: Test-backed El mecanismo de integridad es concreto:
las referencias son artefactos generados, no escritos a mano. Sobrescribirlas
está restringido por un conmutador de entorno GOLDEN_UPDATE explícito, documentado
como una operación rara y siempre revisada. En cambio, las pruebas de snapshot del
motor se regeneran en la primera ejecución y reconocen la desviación mediante una marca de actualización. Las
pruebas de caracterización fijan el comportamiento heredado sin afirmar que sea
correcto. Las tres son herramientas deliberadamente distintas.
Evidence: Standard-backed Una referencia es una especificación mediante ejemplo. Spec: ISO/IEC/IEEE 29119-4, Annex A ISO/IEC/IEEE 29119-4 Annex A señala que las técnicas basadas en especificación y en estructura detectan clases de error distintas y que una estrategia debe combinarlas. Por eso las referencias se sitúan junto a las pruebas unitarias y estructurales en la pirámide de pruebas, no en su lugar.
Ejemplo práctico
Sección titulada «Ejemplo práctico»Una prueba de referencia es simple en lo mecánico; la disciplina está en el flujo de trabajo que la rodea:
<?php
declare(strict_types=1);
// 1. The fixture: a fixed HTML input committed next to the test.// tests/Golden/fixtures/html-inputs/002-basic-table.html
// 2. The pinned references, generated once from known-good behaviour:// 002-basic-table.text.golden (Layer 1 — extracted text)// 002-basic-table.operators.golden (Layer 2 — normalised operators)
// 3. The run compares; ANY difference fails:// vendor/bin/phpunit --testsuite Golden
// 4. An intended behaviour change is the ONLY time references move,// and it is explicit and reviewed — never automatic:// GOLDEN_UPDATE=1 vendor/bin/phpunit --testsuite Golden//// The regenerated *.golden files land in the diff of the same change// that altered behaviour, so a reviewer sees the output delta next to// the code delta and signs off on both together.El ejemplo ilustra el proceso. El código de la prueba solo compara. La referencia es fiable porque una referencia cambiada se revisa como salida en el mismo cambio que alteró el motor.
Concepto erróneo común
Sección titulada «Concepto erróneo común»El error más común es tratar las pruebas de referencia como pruebas byte a byte. Las referencias de NextPDF no son los bytes del archivo: son su texto extraído y sus operadores estructurales normalizados. Comprobar los bytes en bruto fallaría ante una nueva versión de zlib, una etiqueta de subconjunto distinta o una marca de tiempo regenerada, ninguna de las cuales es una regresión. En una semana, la prueba acabaría reaprobándose hasta volverse inútil. (Cuando los bytes exactos deben reproducirse de verdad, ese es el perfil de reproducibilidad a nivel de bits, separado y más estricto, no una referencia.)
El segundo error es suponer que un conjunto de referencias en verde demuestra corrección. Demuestra ausencia de cambio. Una referencia generada a partir de una salida con errores preserva fielmente el error. Las referencias protegen frente a regresiones desde una base de referencia reconocida como buena; no establecen que esa base fuera buena. Para eso están los niveles unitario, estructural y de conformidad.
Límites y fronteras
Sección titulada «Límites y fronteras»Una prueba de referencia responde a exactamente una pregunta: ¿cambió la salida respecto de la referencia anclada? No dice si la referencia llegó a ser correcta alguna vez. Tampoco mide el rendimiento, la conformidad ni la seguridad. Esos son otros niveles. El tamaño del corpus de fixtures, la tasa de aprobación del conjunto y cualquier cifra de cobertura son señales de calidad dinámicas, generadas a partir de artefactos de integración continua y publicadas con la compilación. No se incluyen aquí de forma intencionada, porque podrían quedar obsoletas.
La disposición exacta de directorios, los detalles internos del comparador y el conmutador de actualización pertenecen a la infraestructura de pruebas del motor y pueden evolucionar. La configuración de pruebas es la autoridad si alguna vez discrepa de esta explicación. Esta página no hace ninguna afirmación sobre las herramientas de snapshot o de referencia de ninguna otra biblioteca.
Documentación relacionada
Sección titulada «Documentación relacionada»- La pirámide de pruebas de NextPDF: dónde se sitúa el nivel de referencia entre los cinco y qué demuestra de manera única.
- Pruebas de mutación, explicadas: cómo NextPDF comprueba que sus pruebas, referencias incluidas, detectan realmente los fallos.
- Tipado estricto, en todas partes: el análisis estático que elimina toda una clase de defectos antes de que se ejecute cualquier referencia.
Glosario
Sección titulada «Glosario»- Archivo de referencia (golden file): una salida de referencia anclada, generada a partir de un comportamiento del motor reconocido como bueno y registrada, contra la que una prueba compara en cada ejecución. Nunca se actualiza de forma automática.
- Comparación en dos capas: la comparación de referencias de NextPDF: texto extraído (capa 1) más operadores estructurales normalizados (capa 2), en lugar de bytes en bruto.
- Prueba de snapshot: una técnica relacionada pero distinta en la que la referencia se regenera en la primera ejecución y la desviación se reconoce mediante una marca de actualización.
- Prueba de caracterización: una prueba que fija el comportamiento existente sin afirmar que sea correcto, normalmente para hacer más segura una refactorización.
- Perfil de reproducibilidad: el nivel en el que la salida debe reproducirse: a nivel de bits (bytes exactos), estructural (grafo de objetos y secuencia de operadores, con variaciones benignas de bytes permitidas) o semántico (significado). Las pruebas de referencia aquí afirman el perfil estructural.
GOLDEN_UPDATE: el conmutador de entorno explícito que autoriza sobrescribir las referencias; una operación rara y revisada.