El problema fundamental que aborda Catching JiTTests es la incapacidad de los métodos de prueba tradicionales para escalar al ritmo de la evolución del código en entornos de desarrollo masivos, como el de Meta. Con cientos de millones de líneas de código y un flujo constante de cambios, la detección proactiva de regresiones y bugs se vuelve crítica para mantener la fiabilidad del sistema y la velocidad de desarrollo. Este desafío se ha exacerbado con la creciente complejidad de los sistemas y la adopción de prácticas de integración y despliegue continuo (CI/CD) que demandan ciclos de retroalimentación más rápidos.

La solución propuesta, la generación de pruebas Just-in-Time (JiTTests) asistida por LLMs, representa una evolución en la estrategia de control de calidad. A diferencia de los enfoques de revisión de código basados en IA que emulan el proceso humano, JiTTests genera pruebas ejecutables que demuestran una diferencia de comportamiento concreta introducida por un cambio. Esto permite identificar clases de bugs que una revisión estática o incluso una revisión dinámica limitada podría no detectar, al tiempo que se integra en el flujo de trabajo de los ingenieros para minimizar la fricción y maximizar la tasa de detección de problemas críticos antes de que lleguen a producción.

Arquitectura del Sistema

El sistema Catching JiTTests se articula en un pipeline de cinco etapas que opera de forma asíncrona. La primera etapa, 'Targeting and Triggering', identifica los diffs "riesgosos" del día anterior utilizando un mecanismo similar a un Diff Risk Score (DRS), entrenado con datos históricos de cambios de código para priorizar la generación de pruebas. Esta fase es crucial para optimizar el uso de recursos computacionales, enfocándose en áreas de mayor probabilidad de regresión.

La segunda etapa, 'Two Diff-Aware Test-Generation Workflows', ejecuta dos flujos de generación de pruebas en paralelo. El "dodgy diff workflow" trata cada cambio como un mutante potencial y utiliza LLMs para generar pruebas que expongan diferencias de comportamiento respecto al código base, maximizando la detección de "weak catches". Simultáneamente, el "intent-aware workflow" utiliza un LLM para inferir la intención del diff a partir del código, título y resumen, identificando "riesgos" potenciales. Luego, genera mutantes que representan posibles bugs relacionados con esos riesgos y crea pruebas para "matar" estos mutantes. Las pruebas que fallan en el diff real se recolectan como "weak catches".

Las etapas tres y cuatro se encargan de la evaluación automatizada de los "weak catches". La etapa 'LLM-as-Judge Ensemble' utiliza un conjunto de LLMs para clasificar los "weak catches" como verdaderos o falsos positivos, analizando el código de la prueba, el resultado de la ejecución, el diff y la intención inferida. Este enfoque semántico se complementa con 'Rule-Based Assessor (RubFake)', un sistema determinista basado en reglas que proporciona juicios verificables. La combinación de ambos produce un ranking de candidatos a "strong catches". Finalmente, la etapa 'Human-on-the-Loop' decide cuándo escalar un hallazgo a un ingeniero humano, reduciendo la carga de revisión manual y enfocando la intervención humana en los casos de mayor probabilidad de ser bugs reales.

Flujo de Detección de Bugs con Catching JiTTests

  1. 1 Targeting y Triggering Identificación de diffs "riesgosos" del día anterior usando un Diff Risk Score.
  2. 2 Generación de Pruebas (Dodgy Diff) LLMs generan pruebas para exponer diferencias de comportamiento en el diff (t...
  3. 3 Generación de Pruebas (Intent-Aware) LLMs infieren la intención del diff, identifican riesgos y generan pruebas pa...
  4. 4 LLM-as-Judge Ensemble Conjunto de LLMs evalúa los "weak catches" (pruebas fallidas) para clasificar...
  5. 5 Rule-Based Assessor (RubFake) Sistema basado en reglas complementa la evaluación de LLM-as-Judge con juicio...
  6. 6 Human-on-the-Loop El sistema decide cuándo escalar un hallazgo de alta confianza a un ingeniero...
CapaTecnologíaJustificación
compute Large Language Models (LLMs) Componente central para la generación de pruebas, inferencia de intención del código y evaluación de resultados de pruebas. Se utilizan para crear casos de prueba que demuestran diferencias de comportamiento y para clasificar la validez de los fallos de prueba. vs modelos de IA basados en reglas heurísticas para generación de pruebas, modelos de aprendizaje automático supervisado para clasificación de bugs
data-processing Diff Risk Score (DRS) Mecanismo para priorizar los cambios de código (diffs) que serán objeto de la generación de pruebas. Se entrena con datos históricos para identificar diffs con mayor probabilidad de introducir regresiones, optimizando el uso de recursos computacionales. vs selección aleatoria de diffs, selección basada en heurísticas simples (ej. tamaño del diff, número de archivos afectados)
orchestration Flujos de Trabajo Paralelos (Dodgy Diff & Intent-Aware) Estrategia de ejecución concurrente para maximizar la cobertura de detección de bugs. El flujo "dodgy diff" busca la amplitud de detección de diferencias, mientras que el "intent-aware" se enfoca en la profundidad y relevancia de los riesgos inferidos. vs un único flujo de generación de pruebas, flujos secuenciales
observability Rule-Based False-Positive Killing Environment (RubFake) Sistema determinista basado en reglas para la evaluación de "weak catches". Complementa la naturaleza probabilística de los LLMs, proporcionando una capa de validación verificable y reduciendo la tasa de falsos positivos. vs dependencia exclusiva de la evaluación de LLMs, sistemas de clasificación basados en ML sin reglas explícitas

Trade-offs

Ganancias
  • ▲ Detección temprana de bugs (pre-producción)
  • ▲ Reducción de la ocurrencia de bugs de privacidad (SEVs)
  • ▲ Reducción de la carga de revisión manual para ingenieros
  • ▲ Capacidad de escalar la detección de bugs a un codebase masivo
Costes
  • △ Mayor costo computacional para la generación de pruebas con LLMs
  • △ Complejidad del sistema debido a múltiples flujos y evaluadores (LLM-as-Judge, RubFake)
  • △ Naturaleza no determinista de los juicios de LLMs (mitigada por RubFake)

Fundamentos Teóricos

La generación de pruebas automatizada tiene raíces profundas en la investigación académica, con trabajos pioneros en la década de 1970 y 1980 sobre la generación de casos de prueba a partir de especificaciones formales o análisis de código. El concepto de "mutation testing", donde se introducen pequeños cambios (mutantes) en el código para evaluar la calidad de las pruebas existentes, fue propuesto por Richard Lipton en 1971 y refinado por DeMillo, Lipton y Sayward en 1978. Este principio subyace directamente al "dodgy diff workflow" de Catching JiTTests, que trata los diffs como mutantes para generar pruebas que expongan diferencias de comportamiento.

Más recientemente, la aplicación de técnicas de inteligencia artificial y aprendizaje automático a la generación de pruebas ha ganado tracción. La emergencia de los Large Language Models (LLMs) ha abierto nuevas vías para la generación de código y, por extensión, de pruebas. El uso de LLMs para inferir la "intención" de un cambio de código y generar pruebas dirigidas a "riesgos" específicos, como se ve en el "intent-aware workflow", se alinea con la investigación en programación generativa y síntesis de programas, donde los modelos aprenden a producir código que satisface ciertas propiedades o intenciones. La combinación de enfoques heurísticos (LLM-as-Judge) con sistemas basados en reglas (RubFake) para la clasificación de resultados refleja patrones comunes en sistemas de IA híbridos, buscando equilibrar la flexibilidad y la robustez.