Evaluación de la Cabeza de Defectos y Pruebas de Smoke Testing
La prueba de smoke testing de la cabeza de defectos valida que el pipeline de detección de defectos estructurales de TarmacView — backbone DINOv3 + cabeza MLP d...
Una prueba de humo es una verificación rápida de extremo a extremo de que un pipeline de software se ejecuta sin fallos en datos representativos, produciendo los resultados esperados. Los scripts smoke_*.py de TarmacView validan cada fase del pipeline (analizar, evaluar, detectar grietas, defectos, inspeccionar, visualizar). Cubre el diseño de pruebas de humo, qué verifican las pruebas de humo frente a las pruebas completas y su función en CI/CD.
{{
Una prueba de humo es un procedimiento de verificación automatizado ligero que ejecuta un pipeline de software de extremo a extremo en datos de entrada representativos o mínimos para confirmar que el pipeline se ejecuta hasta completarse sin fallos y produce archivos de salida con la estructura esperada. La prueba realiza una evaluación binaria de aprobado/fallado — si algún paso lanza una excepción no controlada, no produce salida o genera una salida a la que le faltan columnas críticas, la prueba falla y la compilación se rechaza inmediatamente.
El término se origina en la ingeniería de hardware donde la metáfora es literal. Cuando los ingenieros encendían una placa de circuito recién ensamblada por primera vez, observaban si salía humo de componentes quemados. Si aparecía humo, la placa tenía un fallo catastrófico y todas las pruebas posteriores se detenían. La placa defectuosa se reparaba o descartaba antes de que alguien invirtiera tiempo en diagnósticos detallados. La prueba de humo de software aplica el mismo principio: ejecutar el código y verificar si hay “humo” — fallos, excepciones no capturadas, salidas faltantes — antes de invertir tiempo en validación detallada.
En el contexto de los pipelines de software de inspección, una prueba de humo valida que cada etapa de la cadena de procesamiento pueda ejecutarse con datos representativos. Para TarmacView, esto significa alimentar una pequeña imagen de pista o pavimento a través de todo el pipeline — desde la ingesta de imágenes hasta la detección de grietas, clasificación de defectos, evaluación de superficies, mapeo de inspecciones y visualización — y verificar que cada etapa produzca una salida sin errores. Esto es particularmente crítico para el software de aviación, donde los fallos del pipeline pueden retrasar las evaluaciones de infraestructura aeroportuaria que impactan directamente la seguridad de los vuelos.
El término prueba de verificación de compilación (BVT) se utiliza a menudo indistintamente con prueba de humo, siendo Microsoft el adoptante más prominente de esta terminología. Los procesos de desarrollo internos de Microsoft — particularmente para Windows y Office — institucionalizaron las pruebas de humo como una puerta de calidad obligatoria en la década de 1990. Code Complete de Steve McConnell identifica la “compilación diaria y prueba de humo” como la mejor práctica de la industria para la madurez de integración continua. El marco de Ingeniería de Fiabilidad del Sitio (SRE) de Google posiciona las pruebas de humo bajo “pruebas del sistema” — el tipo más simple utilizado específicamente para acortar pipelines de pruebas costosos.
El propósito de las pruebas de humo es triple:
Las pruebas de humo ocupan el primer nivel de la pirámide de pruebas, ejecutándose antes que las pruebas unitarias, las pruebas de integración y las suites de regresión de extremo a extremo. Están diseñadas para completarse en menos de 60 segundos para un pipeline de inspección típico, lo que las hace adecuadas para ejecutarse en cada commit de código en CI/CD. En organizaciones de software de alta madurez, las pruebas de humo se ejecutan en cada push a cualquier rama, no solo a la rama principal, proporcionando la detección más temprana posible de fallos de integración.
El concepto de prueba de humo precede a la ingeniería de software por décadas. El primer uso documentado de la frase aparece en pruebas de fontanería y estufas del siglo XIX. Los fabricantes de estufas encendían un fuego dentro de una estufa recién ensamblada, cerraban todas las compuertas y observaban por dónde escapaba el humo — si el humo emergía de lugares no previstos, la estufa tenía defectos de construcción. Esta misma lógica de “aplicar energía mínima y observar dónde se rompen las cosas” migró a las pruebas electrónicas a mediados del siglo XX y finalmente a la ingeniería de software en las décadas de 1980 y 1990.
Microsoft es ampliamente reconocido por llevar las pruebas de humo a la práctica generalizada de la ingeniería de software. A finales de la década de 1990, las divisiones de Windows y Office de Microsoft adoptaron lo que llamaron Pruebas de Verificación de Compilación (BVT) como un proceso de control obligatorio. Cada compilación nocturna tenía que pasar un conjunto de BVT antes de que la compilación se liberara a los evaluadores internos. Si la BVT fallaba, la compilación se consideraba “rota” y el desarrollador responsable era localizado independientemente de la hora del día. Esta cultura de responsabilidad inmediata por la calidad de la compilación se volvió fundamental para la cultura de ingeniería de Microsoft y fue documentada extensamente en la documentación de MSDN y los libros de Microsoft Press.
La taxonomía de Crosslake Technologies (derivada directamente de la práctica de Microsoft) traza una distinción entre pruebas de humo y BVT. Las pruebas de humo se describen como “superficiales — aseguran que la funcionalidad básica funciona” y se ejecutan en minutos, centradas en funciones críticas. Las BVT se describen como “un superconjunto de las pruebas de humo” que son “ligeramente más exhaustivas” pero aún se ejecutan en minutos, no en horas. Ambas sirven la misma función de control de calidad, pero las BVT incluyen un conjunto más amplio de escenarios de ruta crítica.
Google adoptó las pruebas de humo a través de sus prácticas SRE (Ingeniería de Fiabilidad del Sitio). El Blog de Pruebas de Google trata las pruebas de humo como una práctica conocida y asumida, centrándose más en cómo ponderar los resultados de las pruebas de humo junto con otros tipos de pruebas. La cultura de ingeniería de Google enfatiza la precisión en las pruebas unitarias y la puntuación de confianza ponderada para las verificaciones amplias de tipo prueba de humo, tratando las pruebas de humo como complementarias, no como reemplazos, de las pruebas unitarias rigurosas.
En el dominio del software de aviación, las pruebas de humo se corresponden con la fase de Pruebas de Integración de Hardware/Software descrita en la Sección 6.4.3 de DO-178C. Si bien DO-178C no menciona explícitamente “prueba de humo”, el estándar requiere que el sistema integrado “arranque y las funciones básicas funcionen” antes de proceder con pruebas más profundas. Esto es funcionalmente idéntico a una prueba de humo. Para el software de inspección aeroportuaria que opera bajo Anexo 14 de la OACI — que regula el diseño y las operaciones de aeródromos — las pruebas de humo proporcionan la garantía de fiabilidad del software necesaria para respaldar las evaluaciones del Índice de Condición del Pavimento (PCI) que alimentan los sistemas de gestión de seguridad aeroportuaria.
Comprender dónde encajan las pruebas de humo en la taxonomía más amplia de pruebas es esencial para construir una estrategia equilibrada de garantía de calidad. Los cuatro niveles principales de pruebas cumplen funciones complementarias pero distintas, cada uno dirigido a diferentes modos de fallo en diferentes etapas del ciclo de vida del pipeline.
| Dimensión | Prueba de Humo | Prueba Unitaria | Prueba de Integración | Prueba del Sistema |
|---|---|---|---|---|
| Alcance | Pipeline completo de extremo a extremo | Función o método único | Dos o más componentes que interactúan | Sistema completo en entorno similar a producción |
| Datos | Muestra representativa mínima | Entradas simuladas (mock) | Datos reales pero limitados | Datos a escala de producción |
| Tiempo de ejecución | Segundos a menos de 1 minuto | Milisegundos | Minutos a horas | Horas a días |
| Qué detecta | Fallos, salidas faltantes, errores de importación | Errores lógicos dentro de una función | Desajustes de interfaz, errores de protocolo | Corrección de extremo a extremo, rendimiento |
| Dependencias | Reales (sin simulación) | Simuladas (mock) | Subconjunto real | Pila completa de producción |
| Frecuencia | Cada commit en CI | Cada commit en CI | Por compilación o nocturna | Por lanzamiento |
| Impacto del fallo | Detiene el pipeline | Aislado a una sola función | Bloquea la rama de integración | Bloquea el lanzamiento |
Las pruebas unitarias validan que funciones individuales produzcan salidas correctas para entradas dadas. Simulan todas las dependencias externas — bases de datos, sistemas de archivos, servicios de red, aceleradores de hardware. Una prueba unitaria para una función de detección de grietas podría verificar que identifica correctamente grietas en un arreglo sintético de 10x10 píxeles con posiciones de grieta conocidas. Las pruebas unitarias son estrechas y profundas: verifican la lógica de una sola función de manera exhaustiva, cubriendo casos extremos, condiciones límite y rutas de error. Sin embargo, las pruebas unitarias no pueden detectar fallos de integración porque las dependencias están simuladas — la prueba nunca ejercita la cadena de importación real, la carga de configuración o el flujo de datos entre módulos.
Las pruebas de integración validan que dos o más componentes funcionen juntos correctamente. Utilizan instancias reales pero controladas de las dependencias. Una prueba de integración para TarmacView podría verificar que la etapa de ingesta de imágenes pasa correctamente los datos al modelo de detección de grietas en el formato tensor esperado, con el orden de canales y los parámetros de normalización correctos. Las pruebas de integración son más estrechas que las pruebas de humo en alcance del pipeline pero más profundas en validación de interacción: se centran en límites específicos de componentes en lugar del pipeline completo.
Las pruebas de humo validan que todo el pipeline se ejecute sin fallos. Ejecutan cada etapa en secuencia con datos reales aunque pequeños. Las pruebas de humo son amplias y superficiales — cubren todo el pipeline pero solo verifican que la ejecución se complete y que existan las salidas, no que los resultados numéricos sean correctos. Un cálculo de longitud de grieta que devuelva 47.2 píxeles en lugar de los 42.1 píxeles correctos pasa una prueba de humo siempre que la columna length_px exista y contenga un valor de punto flotante.
Las pruebas del sistema (también llamadas pruebas de extremo a extremo) ejecutan el sistema completo con datos a escala de producción en un entorno similar al de producción. Verifican que el sistema cumple con sus requisitos funcionales y no funcionales, incluyendo precisión, rendimiento y fiabilidad. Las pruebas del sistema son las más costosas de ejecutar y mantener, y se ejecutan solo en candidatos a lanzamiento, no en cada commit.
En la pirámide de pruebas, las pruebas de humo forman la capa base — se ejecutan primero, más rápido y con mayor frecuencia. Si una prueba de humo falla, las pruebas unitarias y de integración en esa compilación generalmente se omiten o se marcan como preventivamente no fiables. Esto ahorra recursos de cómputo y tiempo del desarrollador al fallar rápidamente cuando la ejecución fundamental del pipeline está rota.
El diseño efectivo de pruebas de humo se centra en el concepto de entrada mínima representativa — el conjunto de datos más pequeño que ejercita cada etapa del pipeline sin desencadenar casos extremos dependientes de datos. Esta es la decisión de diseño más importante al construir una suite de pruebas de humo.
Principio 1: Mínimo pero no trivial. La entrada debe ser lo suficientemente grande como para pasar por cada etapa del pipeline sin tomar rutas de código que eviten la lógica de procesamiento real. Una imagen de un solo píxel es trivial — pasaría por la carga de imagen pero los algoritmos de procesamiento tomarían rutas de código degeneradas que nunca se ejecutan con datos reales. Una imagen de 256x256 píxeles de pavimento de pista real es mínima pero representativa: ejercita algoritmos de procesamiento basados en teselas, rutinas de normalización de color y rutas de inferencia del modelo sin requerir tiempo de cómputo excesivo.
Principio 2: Representativa de los datos de producción. La entrada debe tener el mismo formato de archivo, profundidad de color, estructura de metadatos y propiedades estadísticas que los datos de producción. Si los datos de producción provienen de una cámara aérea Phase One iXM-RS150F que captura archivos TIFF de 16 bits con metadatos EXIF GPS incrustados, la entrada del smoke test debe coincidir con estas características. Usar datos sintéticos que difieren de los datos de producción anula el propósito del smoke test porque las fallas del pipeline a menudo provienen de propiedades inesperadas de los datos reales — etiquetas EXIF faltantes, perfiles de color inesperados, cadenas de proyección GeoTIFF no estándar.
Principio 3: Fija y controlada por versiones. Las entradas de los smoke tests deben estar registradas en el control de versiones junto con el código como archivos binarios o gestionadas mediante Git LFS (Large File Storage). Nunca deben cambiar sin una revisión explícita a través de pull requests. Una entrada cambiante hace imposible distinguir entre regresiones del pipeline y cambios en los datos de prueba — un smoke test que pasa hoy y falla mañana podría indicar una regresión de código o una entrada de prueba modificada. Controlar las entradas por versiones elimina esta ambigüedad.
Principio 4: Rápido de procesar. La ejecución total del conjunto de smoke tests no debe exceder los 60 segundos para un pipeline típico y 3 minutos para pipelines complejos de múltiples etapas como el software de inspección. Esta restricción determina el tamaño de la entrada. Para pipelines de inspección basados en imágenes, una sola imagen de 512x512 píxeles es típicamente suficiente. Para pipelines de video, un solo fotograma o un clip de 2 segundos. Para pipelines LiDAR, un segmento de línea de vuelo que cubra 100 metros de pavimento.
Principio 5: Contiene características conocidas. La entrada de prueba debe contener las características que cada etapa del pipeline está diseñada para detectar. Un smoke test para detección de grietas es inútil si la imagen de entrada no contiene grietas — el pipeline podría omitir silenciosamente la detección de grietas y aún así pasar. Las entradas de prueba deben ser seleccionadas para contener al menos una instancia de cada característica detectable con una verdad de referencia conocida que pueda ser consultada durante el análisis de fallas.
Para el pipeline de inspección de TarmacView, la entrada del smoke test es una sola ortofoto RGB de 1024x768 píxeles de pavimento aeroportuario capturada a 1 mm de distancia de muestra en terreno (GSD). La imagen contiene al menos una grieta visible, un defecto superficial (ej. desprendimiento o desconchamiento) y marcas de pavimento claras. Esta única imagen:
El tiempo de procesamiento esperado para esta única imagen a través del pipeline completo es inferior a 30 segundos en hardware de CI, dejando margen para los smoke tests restantes del conjunto. La imagen de prueba se almacena en el repositorio bajo tests/data/smoke/ y está controlada por versiones mediante Git LFS.
El pipeline de inspección de TarmacView se valida mediante un conjunto de scripts de smoke test dedicados, cada uno cubriendo una fase específica del pipeline. Estos scripts residen en el directorio scripts/ siguiendo la convención de nomenclatura smoke_<fase>.py. Cada script está diseñado para ejecutarse tanto de forma independiente (para depuración durante el desarrollo) como como parte del conjunto de CI (para validación automatizada).
{{
Este script valida la fase de análisis de imágenes. Lee una sola ortofoto representativa, ejecuta el pipeline de análisis completo a través del módulo de procesamiento de imágenes y verifica:
El script acepta un argumento --input que apunta a la imagen de prueba y un argumento --output-dir que especifica dónde debe escribir los resultados el pipeline. Si el pipeline falla durante cualquier paso de procesamiento, la excepción se captura y la prueba devuelve un informe de falla estructurado.
Este script valida la fase de evaluación de la condición del pavimento. Toma la salida de la fase de análisis (o un archivo de análisis pregenerado almacenado en el control de versiones), ejecuta el algoritmo de evaluación de condición y verifica:
pavement_id condition_index severity extent date_assessedEl algoritmo de evaluación en TarmacView sigue el estándar ASTM D5340 para el cálculo de PCI aeroportuario adaptado para inspección automatizada basada en imágenes. El smoke test no verifica que los valores de PCI sean numéricamente correctos — solo verifica que el cálculo se ejecuta, produce resultados en el formato esperado y los escribe en disco.
Este script valida la fase de detección de grietas. Ejecuta el modelo de detección de grietas sobre una imagen de prueba que se sabe contiene grietas y verifica:
crack_id length_px width_px orientation confidence classificationEl modelo de detección de grietas utilizado por TarmacView es una arquitectura U-Net con un backbone ResNet-50 entrenada con imágenes de pavimento etiquetadas de múltiples aeropuertos. La imagen de entrada del smoke test fue seleccionada específicamente del conjunto de validación, lo que significa que contiene grietas que el modelo ha visto durante el entrenamiento pero no durante la evaluación del conjunto de prueba.
Este script valida la fase de clasificación de defectos superficiales. Ejecuta el clasificador de defectos sobre una imagen de prueba que contiene defectos conocidos (desprendimiento, desconchamiento, parcheo, meteorización) y verifica:
defect_id defect_type area_px severity confidence timestampEl clasificador de defectos utiliza una arquitectura Mask R-CNN que produce máscaras de segmentación de instancias para cada defecto detectado. El smoke test verifica que la máscara de salida tenga las dimensiones correctas y que el archivo de inventario contenga las columnas del esquema esperado. No verifica que las clasificaciones de defectos sean correctas — eso requiere un conjunto de validación separado con datos etiquetados de verdad de referencia.
Este script valida la fase de cartografía topográfica. Toma los datos de grietas y defectos producidos por las etapas anteriores, ejecuta el módulo de cartografía geoespacial y verifica:
El módulo de cartografía topográfica utiliza los metadatos de georreferenciación de la ortofoto para realizar una transformación proyectiva de coordenadas de píxeles a coordenadas geográficas. El smoke test verifica que esta transformación produce coordenadas geográficas válidas dentro del cuadro delimitador esperado para la imagen de prueba. Una fotografía de la ubicación de la imagen de prueba tomada en el aeropuerto proporciona una referencia visual cruzada para el análisis de fallas.
Este script valida la fase de visualización y cabezal de segmentación — la etapa final del pipeline que produce salida legible para humanos. Toma las salidas procesadas del pipeline, ejecuta el renderizador de visualización y verifica:
La fase de visualización es a menudo el primer lugar donde los errores acumulativos del pipeline se hacen visibles. Una etapa de detección de grietas que produce una máscara en el espacio de coordenadas incorrecto generará una visualización donde las superposiciones de grietas aparecen desplazadas respecto a la imagen base. El smoke test detecta esto indirectamente si el renderizado falla, pero es la prueba de regresión de inspección visual — no el smoke test — la que detecta regresiones en la calidad visual.
Estos smoke tests están diseñados para ejecutarse en secuencia pero también pueden ejecutarse de forma independiente si las salidas de etapas anteriores están almacenadas en caché. El conjunto completo se completa en menos de 3 minutos en hardware de CI. Cada prueba genera un informe JSON estructurado con los siguientes campos:
| Campo | Tipo | Descripción |
|---|---|---|
test_name | string | Nombre único de la prueba (ej. “smoke_crack”) |
passed | boolean | Si la prueba pasó (true) o falló (false) |
duration_ms | integer | Tiempo de ejecución en milisegundos |
output_files | array of strings | Rutas a los archivos de salida creados durante la prueba |
failure_reason | string o null | Razón de falla legible para humanos si la prueba falló |
input_path | string | Ruta a los datos de entrada utilizados para la prueba |
pipeline_version | string | SHA del commit de Git o etiqueta de versión del código del pipeline |
El ejecutor de pruebas agrega los informes JSON individuales en un resumen del conjunto que se publica en el panel de CI y opcionalmente se envía a Slack o correo electrónico para notificación en tiempo real.
Los smoke tests son deliberadamente limitados en lo que afirman. Verifican tres categorías de condiciones y nada más. Este alcance limitado es intencional — mantiene las pruebas rápidas, deterministas y fáciles de mantener.
La afirmación más fundamental: ¿el código se ejecuta sin lanzar una excepción no manejada? Esto cubre:
Un pipeline que falla al inicio o durante la ejecución hace fallar el smoke test inmediatamente. La razón de la falla se captura a partir del traceback de la excepción, proporcionando a los desarrolladores un puntero directo a la ubicación del código donde ocurrió la falla.
Después de que la ejecución se completa, el smoke test verifica que los archivos de salida existen en las rutas esperadas. Esto cubre:
Un pipeline que afirma haber terminado pero no produce archivos de salida hace fallar el smoke test. Esto detecta fallas silenciosas donde el pipeline termina limpiamente pero omite operaciones críticas de escritura debido a rutas de salida mal configuradas o lógica condicional que se evalúa como falsa inesperadamente.
Para cualquier salida tabular (CSV, Parquet, colección de características GeoJSON), el smoke test verifica que las columnas esperadas existen por nombre. Esta es una verificación de integridad estructural — el esquema de columnas debe coincidir con lo que los consumidores posteriores esperan.
| Tipo de Salida | Columnas Requeridas |
|---|---|
| Inventario de grietas | crack_id length_px width_px orientation confidence classification |
| Inventario de defectos | defect_id defect_type area_px severity confidence timestamp |
| Evaluación de condición | pavement_id condition_index severity extent date_assessed method |
| Cartografía topográfica | feature_id latitude longitude geometry_type crs_epsg accuracy_m |
La prueba utiliza una verificación de existencia de columnas (no una verificación de tipo, no una verificación de rango de valores). Esto es intencional — la existencia de columnas es la garantía mínima de integridad estructural. Las verificaciones de tipo y rango pertenecen a las pruebas de integración y validación, donde el costo de ejecutarlas está justificado por la profundidad de la información que proporcionan.
La cuarta categoría de verificación que realizan los smoke tests — a menudo pasada por alto — es la compatibilidad de formato de datos. El smoke test verifica que los archivos de salida pueden ser leídos por los consumidores posteriores esperados. Para TarmacView esto significa:
Esto detecta discrepancias de versión de formato — por ejemplo, si la biblioteca Parquet se actualiza y cambia su codificación, o si la especificación GeoJSON evoluciona y la salida del pipeline ya no cumple.
Igualmente importante es entender lo que los smoke tests excluyen deliberadamente. Malinterpretar esto lleva a una falsa confianza en la corrección del pipeline — un smoke test que pasa no significa que el pipeline sea correcto, solo que no está catastróficamente roto.
Los smoke tests no verifican que los valores calculados sean correctos. Un cálculo de longitud de grieta que devuelve 47.2 píxeles en lugar de los 42.1 píxeles correctos pasa un smoke test siempre que la columna length_px exista y contenga un float. La validación de precisión pertenece a las pruebas unitarias, donde el valor correcto está codificado, y a las pruebas de integración, donde los resultados se comparan con mediciones manuales de inspectores certificados.
Para los pipelines de inspección aeronáutica que operan bajo el Anexo 14 de la OACI, la precisión numérica es crítica porque las evaluaciones de condición informan directamente la priorización de mantenimiento y la asignación de presupuesto. Un pipeline que pasa los smoke tests pero produce puntuaciones PCI inexactas podría llevar a decisiones de mantenimiento incorrectas. Esta es la razón por la que los smoke tests son solo la primera puerta — deben ser seguidos por pruebas de validación centradas en la precisión.
Los smoke tests utilizan entradas representativas pero no adversariales. No prueban:
El manejo de casos extremos se valida mediante pruebas de casos extremos dedicadas que apuntan específicamente a cada condición límite. Estas pruebas son más costosas de ejecutar y típicamente se ejecutan nocturnamente en lugar de en cada commit.
Los smoke tests verifican que el pipeline se completa, no que se complete dentro de un presupuesto de rendimiento. Un pipeline que tarda 10 segundos por imagen en los smoke tests pero se espera que procese 100 imágenes por segundo en producción pasa los smoke tests sin problemas. La validación del rendimiento requiere pruebas de benchmark dedicadas con datos a escala de producción y aserciones de temporización.
Para los pipelines de inspección aeroportuaria, el rendimiento es crítico porque los aeropuertos procesan cientos de imágenes de pavimento por levantamiento. Una regresión de rendimiento de 10x podría aún pasar los smoke tests en una sola imagen, pero haría inviables los levantamientos completos. Los benchmarks de rendimiento con umbrales de temporización son la herramienta adecuada para detectar tales regresiones.
Los smoke tests cubren solo la ruta de ejecución principal. Las características que no están en la ruta crítica — formatos de salida alternativos, registro opcional, telemetría, pistas de auditoría, características de exportación experimentales — no están cubiertas. La regresión en estas áreas debe ser detectada por conjuntos de pruebas de regresión que apunten específicamente a la funcionalidad no crítica.
Los smoke tests no verifican que los valores de datos sean internamente consistentes. Por ejemplo, un smoke test verifica que la columna crack_id existe, pero no verifica que todos los valores de crack_id sean únicos, no nulos o estén dentro de rangos esperados. La validación de calidad de datos requiere pruebas de calidad de datos dedicadas utilizando frameworks como Great Expectations o Pandera que definan contratos de datos y validen conjuntos de datos contra ellos.
Los smoke tests ofrecen el máximo valor cuando se integran en el pipeline de integración continua y despliegue continuo (CI/CD). Su ubicación en el flujo de trabajo del pipeline determina su efectividad como puerta de calidad.
{{
En un flujo de trabajo típico de CI/CD, los smoke tests se ejecutan en la etapa de verificación de compilación inmediatamente después de la compilación y antes de cualquier otro conjunto de pruebas:
Commit de Código → Compilar → Lint → Pruebas Unitarias → Smoke Tests → Pruebas de Integración → Pruebas de Validación → Desplegar
El orden exacto depende de la estrategia de pruebas del proyecto. Algunas organizaciones ejecutan las pruebas unitarias antes que los smoke tests, argumentando que las pruebas unitarias son más rápidas y detectan errores de lógica. Otras ejecutan primero los smoke tests, argumentando que un pipeline que falla en la ejecución básica debe ser rechazado sin perder tiempo en pruebas unitarias. El pipeline de TarmacView ejecuta pruebas unitarias y smoke tests en paralelo después de una compilación exitosa, ya que cubren modos de falla independientes y no tienen interdependencias.
Esta ubicación asegura que si la compilación produce un pipeline que falla en la ejecución básica, no se consume más infraestructura de pruebas. El ciclo de retroalimentación se mide en minutos en lugar de horas. Un desarrollador que envía un commit que rompe la cadena de importación recibe una notificación de falla de CI en 2-3 minutos, en lugar de esperar 4 horas a que el conjunto de pruebas de integración falle.
El pipeline de CI/CD utiliza una puerta estricta: si algún smoke test falla, el pipeline se detiene y no continúa a etapas posteriores. La compilación se marca como fallida y los desarrolladores son notificados con el informe de falla del smoke test. No se permite ninguna anulación manual en la configuración predeterminada — un conjunto de smoke tests que pasa es una condición necesaria para el despliegue.
Esta lógica de puerta previene los siguientes escenarios:
La puerta se implementa en la configuración de la plataforma de CI. Para CircleCI esto significa configurar dependencias del flujo de trabajo para que el trabajo smoke-test se ejecute antes que integration-test y deploy. Para GitHub Actions esto significa usar la palabra clave needs: para forzar el orden de los trabajos.
Los smoke tests dentro del conjunto pueden ejecutarse en paralelo si prueban etapas independientes del pipeline. El conjunto de smoke tests de TarmacView utiliza paralelismo cuando es posible:
smoke_crack.py y smoke_defect.py no tienen interdependencias y pueden ejecutarse concurrentemente, reduciendo el tiempo total del conjunto en un 40%smoke_analyze.py debe completarse antes que smoke_assess.py ya que la evaluación consume la salida del análisissmoke_survey.py depende de las salidas de grietas y defectossmoke_seg_head.py depende de todas las salidas de etapas anterioresLa estrategia de ejecución paralela se configura en el YAML del pipeline de CI utilizando paralelismo a nivel de trabajo. Cada trabajo se ejecuta en su propio contenedor con dependencias aisladas, previniendo la contención de recursos.
La integración con CI/CD incluye reportes automatizados con múltiples canales:
# .circleci/config.yml
version: 2.1
jobs:
smoke-test:
docker:
- image: tarmacview/pipeline:ci
parallelism: 3
steps:
- checkout
- run: pip install -r requirements.txt
- run: python scripts/smoke_analyze.py --input tests/data/smoke_image.tif --output-dir /tmp/smoke-output
- run:
name: "Smoke tests en paralelo"
command: |
python scripts/smoke_crack.py --input tests/data/smoke_image.tif --output-dir /tmp/smoke-output &
python scripts/smoke_defect.py --input tests/data/smoke_image.tif --output-dir /tmp/smoke-output &
wait
- run: python scripts/smoke_assess.py --input /tmp/smoke-output/cracks.parquet --output-dir /tmp/smoke-output
- run: python scripts/smoke_survey.py --input /tmp/smoke-output --output-dir /tmp/smoke-output
- run: python scripts/smoke_seg_head.py --input /tmp/smoke-output --output-dir /tmp/smoke-output
- store_artifacts:
path: /tmp/smoke-output
workflows:
version: 2
build-and-test:
jobs:
- build
- unit-tests:
requires: [build]
- smoke-test:
requires: [build]
- integration-tests:
requires: [smoke-test]
- deploy:
requires: [integration-tests]
Escribir smoke tests efectivos requiere disciplina. La prueba debe ser rápida, confiable y centrada únicamente en lo que está diseñada para detectar. Cada smoke test sigue el mismo patrón fundamental: ejecutar la etapa del pipeline, verificar la existencia de la salida, verificar la corrección mínima del esquema, reportar aprobado/fallado en JSON estructurado.
# smoke_crack.py — patrón simplificado
import sys
import json
import time
from pathlib import Path
import pandas as pd
def test_smoke_crack(input_path: str, output_dir: str) -> dict:
result = {
"test_name": "smoke_crack",
"passed": False,
"duration_ms": 0,
"output_files": [],
"failure_reason": None,
"input_path": input_path,
"pipeline_version": "unknown"
}
start = time.time()
try:
# Paso 1: Obtener la versión del pipeline
from tarmacview import __version__
result["pipeline_version"] = __version__
# Paso 2: Ejecutar la etapa del pipeline con importaciones reales
from tarmacview.pipeline.crack import detect_cracks
output = detect_cracks(input_path, output_dir)
# Paso 3: Verificar que el archivo de salida existe y no está vacío
output_path = Path(output["crack_mask_path"])
assert output_path.exists(), f"Archivo de salida no encontrado: {output_path}"
assert output_path.stat().st_size > 0, f"El archivo de salida está vacío: {output_path}"
result["output_files"].append(str(output_path))
# Paso 4: Verificar columnas clave en la salida tabular
if output.get("crack_inventory_path"):
inv_path = Path(output["crack_inventory_path"])
assert inv_path.exists(), f"Archivo de inventario no encontrado: {inv_path}"
df = pd.read_parquet(inv_path)
required_columns = [
"crack_id", "length_px", "width_px",
"orientation", "confidence", "classification"
]
for col in required_columns:
assert col in df.columns, f"Falta la columna requerida: {col}"
result["output_files"].append(str(inv_path))
# Paso 5: Verificar que las dimensiones de la máscara de salida coinciden con la entrada
from PIL import Image
input_img = Image.open(input_path)
mask_img = Image.open(output_path)
assert input_img.size == mask_img.size, \
f"Las dimensiones de la máscara {mask_img.size} no coinciden con la entrada {input_img.size}"
result["passed"] = True
except Exception as e:
result["failure_reason"] = f"{type(e).__name__}: {str(e)}"
result["passed"] = False
result["duration_ms"] = int((time.time() - start) * 1000)
return result
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--input", required=True)
parser.add_argument("--output-dir", default="/tmp/smoke-output")
args = parser.parse_args()
result = test_smoke_crack(args.input, args.output_dir)
print(json.dumps(result, indent=2))
sys.exit(0 if result["passed"] else 1)
Una aserción por categoría. Afirmar que la ejecución se completa. Afirmar que la salida existe. Afirmar que las columnas existen. No afirmar rangos numéricos, tamaños de archivo exactos o métricas de calidad de datos. Cada aserción adicional aumenta el costo de mantenimiento de la prueba y reduce su confiabilidad.
Usar importaciones reales. No simular módulos del pipeline. El smoke test debe ejercitar la cadena de importación real para detectar errores de importación y dependencias faltantes. Un smoke test que usa unittest.mock para suprimir errores de importación anula su propio propósito.
Configuración y limpieza mínimas. La prueba no debe requerir configuración de base de datos, inicio de servicios ni configuración externa más allá del archivo de entrada de prueba. Si se requiere configuración, debe ser parte de la definición del trabajo de CI, no del script de prueba. Cada smoke test debe poder ejecutarse en el portátil de un desarrollador con un solo comando.
Determinista. La misma entrada debe producir siempre el mismo resultado de aprobado/fallado. Las semillas aleatorias deben fijarse en la configuración del pipeline. Los archivos de entrada de prueba deben estar controlados por versiones. Los smoke tests no deterministas son peores que inútiles — erosionan la confianza en toda la infraestructura de pruebas.
Salida estructurada autocontenida. La prueba debe imprimir una salida JSON estructurada al completarse, facilitando que los sistemas de CI analicen los resultados sin necesidad de análisis de registros personalizados. El esquema JSON debe ser consistente en todos los smoke tests del conjunto.
Rápida. Cada prueba debe completarse en menos de 60 segundos en hardware de CI. Si una prueba excede consistentemente este límite, optimice la prueba antes de agregarla al conjunto. Un smoke test que tarda 5 minutos será omitido por los desarrolladores que ejecuten pruebas localmente.
except Exception genérico puede pasar por alto fallas de importación. Deje que algunas excepciones se propaguen o, como mínimo, registre los errores de importación por separado.--output-dir para permitir entornos de ejecución flexibles.Cuando un smoke test falla, el flujo de trabajo de desarrollo debe pasar de “desarrollar” a “diagnosticar y corregir”. La interpretación efectiva de fallas sigue un enfoque estructurado que mapea los síntomas de falla a las causas raíz probables.
| Síntoma de Falla | Causa Raíz Probable | Acción Inmediata |
|---|---|---|
| ImportError | Dependencia faltante, módulo renombrado, módulo eliminado, conflicto de versiones | Verificar requirements.txt y cambios recientes de importación en el diff del commit |
| ModuleNotFoundError | Paquete no instalado o no en el path de Python | Verificar que el entorno coincida con el archivo lock, verificar importaciones condicionales |
| FileNotFoundError | Ruta de salida cambiada, problema de permisos de escritura, directorio faltante | Verificar la configuración de la ruta de salida en commits recientes, verificar la lógica de creación de directorios |
| PermissionError | Permisos de sistema de archivos insuficientes en el contenedor de CI | Verificar los permisos del Dockerfile y el usuario del ejecutor de CI |
| Archivo de salida vacío | La etapa se completó pero omitió la lógica de procesamiento debido a un condicional que se evaluó inesperadamente | Agregar registro de depuración para trazar la ruta de ejecución, verificar retornos tempranos |
| Columna faltante | Cambio de esquema en una etapa anterior, columna renombrada, columna eliminada, discrepancia de tipos | Comparar esquemas de columnas entre etapas del pipeline, verificar PRs recientes que toquen definiciones de esquema |
| Segfault o OOM | Fuga de memoria, asignación de memoria sin límite, fallo de extensión nativa | Perfilar con entrada reducida, verificar bucles infinitos, verificar la gestión de memoria de CUDA |
| Timeout | Bucle infinito, E/S bloqueante, interbloqueo, API externa lenta | Agregar envoltorio de timeout, verificar problemas de seguridad en hilos, verificar conectividad de red |
| AssertionError en dimensiones | Operación de redimensionamiento eliminada, tamaño de entrada del modelo cambiado, conversión de tipo de datos cambió la forma | Verificar parámetros de procesamiento de imágenes, verificar especificaciones de entrada del modelo |
| Error de CUDA | Discrepancia del controlador de GPU, conflicto de versión de CUDA, memoria de GPU insuficiente | Verificar la versión del toolkit de CUDA, verificar los controladores de GPU de la imagen Docker |
Cuando un smoke test falla en CI, el flujo de trabajo de respuesta recomendado es:
Revisar el informe de falla. La salida JSON estructurada del smoke test incluye el campo failure_reason que contiene el tipo de excepción y el mensaje. Este es el camino más rápido para entender qué se rompió.
Identificar si la falla es una regresión de código o un problema de infraestructura. Un ModuleNotFoundError en un paquete que estaba instalado ayer sugiere una regresión. Un Timeout que aparece en todas las compilaciones simultáneamente sugiere un problema de infraestructura (caída de red, degradación del ejecutor de CI).
Revertir si la causa raíz no es obvia en 15 minutos. El conjunto de smoke tests es rápido precisamente para permitir una reversión rápida. Una compilación que falla los smoke tests debe revertirse inmediatamente para desbloquear el pipeline de CI para otros desarrolladores.
Investigar con la entrada de prueba. Ejecutar el smoke test fallido localmente con la misma entrada de prueba controlada por versiones. Reproducir la falla localmente elimina variables específicas de CI (diferencias de contenedor, límites de recursos, problemas de paralelismo).
Corregir y agregar una prueba unitaria. Una vez identificada la causa raíz, corregir el código y agregar una prueba unitaria al nivel apropiado que habría detectado la falla. Esto evita que la misma clase de regresión se repita.
Verificar que la corrección pase los smoke tests. Ejecutar el conjunto completo de smoke tests localmente antes de enviar la corrección. Esto asegura que la corrección no introduzca nuevas fallas en otras etapas del pipeline.
Los smoke tests pueden producir falsos positivos — la prueba falla pero el pipeline realmente es funcional. Las causas comunes incluyen:
Los smoke tests inestables erosionan la confianza en la infraestructura de pruebas. Los desarrolladores que ven fallar los smoke tests aleatoriamente comenzarán a ignorar las fallas. La solución es des-inestabilizar agresivamente: identificar la causa raíz de la inestabilidad y endurecer la prueba. Si una prueba no puede hacerse confiable con un esfuerzo razonable, debe moverse a un conjunto de pruebas de menor prioridad o reemplazarse con un diseño más robusto.
Para el software aeronáutico, incluyendo los pipelines de inspección aeroportuaria, los smoke tests tienen una importancia adicional debido a la naturaleza crítica para la seguridad del dominio. Bajo DO-178C (Consideraciones de Software en Sistemas y Equipos Aerotransportados — Certificación), la verificación de software sigue un proceso riguroso basado en requisitos. Si bien DO-178C no menciona explícitamente “smoke testing”, el concepto de Pruebas de Integración Hardware/Software definido en la Sección 6.4.3 requiere que el sistema integrado “arranque y las funciones básicas funcionen” — el equivalente funcional de un smoke test.
Bajo el Anexo 14 de la OACI Volumen I — Diseño y Operaciones de Aeródromos — la condición de los pavimentos aeroportuarios afecta directamente la seguridad de las aeronaves. Una falla del pavimento en una pista puede causar daños a la aeronave o pérdida de control durante el despegue y aterrizaje. El software utilizado para la inspección automatizada de pavimentos debe, por lo tanto, cumplir con estándares de confiabilidad acordes con las implicaciones de seguridad de su salida. Los smoke tests proporcionan la primera línea de defensa contra errores de software que podrían comprometer las evaluaciones de la condición del pavimento.
Para TarmacView, los smoke tests son parte de un marco de aseguramiento de calidad de software más amplio que incluye:
Este enfoque multicapa asegura que los smoke tests sirvan como la primera puerta sin ser la única puerta. Un smoke test que pasa significa que el pipeline es estructuralmente sólido. Pero son las pruebas de integración, las pruebas de validación y los benchmarks de rendimiento los que proporcionan la confianza necesaria para usar la salida de TarmacView en decisiones reales de mantenimiento aeroportuario.
El smoke testing es una práctica fundamental de calidad de software que ofrece un valor desproporcionado en relación con su costo de implementación. Para pipelines de software de inspección como TarmacView, los smoke tests detectan fallas de integración — importaciones rotas, archivos faltantes, discrepancias de esquema — en segundos en lugar de horas. Sirven como la primera puerta en CI/CD, rechazando compilaciones inestables antes de que consuman infraestructura de pruebas. El conjunto de smoke tests de TarmacView cubre cada fase del pipeline, desde la ingesta de imágenes hasta la detección de grietas, clasificación de defectos, evaluación de superficies, cartografía topográfica y visualización, con cada prueba verificando que la etapa se ejecuta, produce salida y mantiene los esquemas de columna esperados.
La clave para un smoke testing efectivo es entender su alcance limitado. Los smoke tests verifican que el pipeline se ejecuta y produce salida. No verifican precisión, rendimiento, manejo de casos extremos o calidad de datos. Estos son validados por otros tipos de pruebas en el marco más amplio de aseguramiento de calidad. Cuando los smoke tests se diseñan con esta disciplina — entradas representativas mínimas, tiempos de ejecución rápidos, cobertura amplia pero superficial — proporcionan la detección de fallas rápida y confiable que hace que los pipelines de CI/CD sean efectivos para el software aeronáutico crítico para la seguridad.
TarmacView utiliza pruebas de humo automatizadas para validar cada etapa de su pipeline de inspección. Contáctenos para conocer cómo mantenemos la calidad del software para el análisis crítico de infraestructura aeroportuaria.
La prueba de smoke testing de la cabeza de defectos valida que el pipeline de detección de defectos estructurales de TarmacView — backbone DINOv3 + cabeza MLP d...
Explora los conceptos avanzados de pruebas de rendimiento de software y aseguramiento de la calidad (QA), incluidos procesos, metodologías, herramientas, métric...
Un procedimiento de prueba es un método documentado, paso a paso, para verificar sistemáticamente el cumplimiento, la corrección y el rendimiento de los sistema...