Pruebas de caracterización: anota lo que hace el sistema viejo antes de cambiarlo
Antes de refactorizar o reemplazar un sistema viejo, registra lo que hace hoy, incluidas sus partes raras. Cómo las pruebas de caracterización, el golden master y el tráfico real capturado te dan una red de seguridad, y cómo la IA acelera escribirlas.
El momento más riesgoso en un proyecto con software heredado es el primer cambio. No hay pruebas ni una especificación al día, y quienes sabían por qué funciona así ya no están. Antes de cambiar cualquier cosa, necesitas un registro de lo que el sistema hace hoy. Ese registro es un conjunto de pruebas de caracterización.
Si lideras el equipo: qué preguntar
- Antes de cambiar el sistema viejo, ¿tenemos pruebas que registren lo que hace hoy, incluidas las partes raras?
- ¿Esas pruebas se construyeron con entradas reales, o solo con casos que alguien imaginó?
- Cuando el código nuevo se comporta distinto al viejo, ¿quién decide si es una corrección o una regresión?
Una prueba normal verifica que el código hace lo que debería. Una de caracterización verifica que hace lo que hace. No juzga. Describe. Si el módulo viejo de facturas redondea un total hacia abajo en lugar de al centavo más cercano, la prueba de caracterización espera ese redondeo hacia abajo. Si eso es correcto se decide después, a propósito, no por accidente en producción.
Por qué “lo que hace” le gana a “lo que debería hacer”
Un sistema viejo en uso diario fue moldeado por años de correcciones, excepciones y parches. Clientes, reportes y otros sistemas dependen de su comportamiento exacto, incluso del que nadie diseñaría hoy. Si escribes las pruebas a partir de la especificación, pruebas tu idea del sistema. Si las escribes a partir de la observación, pruebas el sistema con el que de verdad opera tu negocio.
La meta es una red de seguridad: una vez que el comportamiento actual queda fijado, cualquier cambio que lo altere hace fallar una prueba.
Golden master y snapshots
Escribir una aserción por cada comportamiento es lento en código grande y poco conocido. El enfoque más rápido es el golden master (la “copia maestra”):
- Elige un punto de entrada: una función, un endpoint, un proceso por lotes, un reporte.
- Aliméntalo con un conjunto amplio de entradas.
- Guarda cada salida completa, como archivos: el cuerpo de la respuesta, el documento generado, las filas escritas en la base de datos.
- De ahí en adelante, corre las mismas entradas y compara las salidas nuevas con las guardadas. Cualquier diferencia hace fallar la prueba.
Las pruebas de snapshot son la misma idea a menor escala: la primera corrida guarda la salida y las siguientes comparan contra ella. Las dos requieren cuidado. Quita o congela todo lo que cambia por sí solo, como fechas y horas, identificadores generados, valores aleatorios y el orden de colecciones sin orden, o las pruebas van a fallar por razones que no tienen nada que ver con tu cambio.
Captura entradas y salidas reales
Las mejores entradas vienen de producción, que contiene los casos que nadie pensó. Fuentes útiles:
- Registros de peticiones de APIs y endpoints web, reproducidos contra una copia de prueba.
- Archivos de entrada que procesaron los procesos por lotes, junto con los archivos que produjeron.
- Una capa de grabación agregada temporalmente delante del código viejo, que guarda cada petición y cada respuesta en el momento.
Dos reglas. Los datos personales y sensibles se enmascaran o se reemplazan antes de llegar a las pruebas. Y la muestra se elige a propósito: los casos comunes, pero también los extremos, como montos en cero, nombres muy largos, formatos viejos de registros y fechas de fin de mes y fin de año, porque en los casos raros es donde los sistemas viejos esconden sus reglas.
Dónde la IA acelera esto
Las herramientas de IA hacen bien este trabajo, con una persona revisando:
- Leer el código. Pídele al modelo que liste cada rama de una función y la entrada que llegaría a cada una.
- Redactar pruebas a partir del tráfico. Dale un conjunto de peticiones y respuestas capturadas y el código del módulo, y que escriba las pruebas: preparación, entradas, salidas esperadas.
- Llenar los huecos. Corre las pruebas con una herramienta de cobertura, muéstrale al modelo las líneas que nunca se ejecutaron y pídele entradas que lleguen a ellas.
La regla: los valores esperados salen de correr el sistema viejo real, nunca de lo que el modelo cree que hace el código. El modelo escribe la prueba; el sistema viejo pone la respuesta.
Decide después qué rarezas son errores
Un conjunto de pruebas de caracterización va a fijar comportamiento que parece incorrecto. No lo corrijas mientras construyes la red. Marca esas pruebas, haz una lista y revísala con las personas dueñas del proceso de negocio. Cada una se convierte en una de tres decisiones: mantenerla (alguien depende de eso), corregirla (es un error real, y la prueba cambia junto con la corrección, a propósito) o retirarla (nadie usa ya ese camino).
Así empezamos nuestro trabajo de modernización de software: primero registrar, después cambiar.
Lista: antes del primer cambio
- Puntos de entrada elegidos: las funciones, endpoints, procesos y reportes que el cambio va a tocar.
- Entradas reales capturadas, con los datos personales enmascarados.
- Casos extremos elegidos a propósito: cero, vacío, muy largo, formatos viejos, fin de mes y de año.
- Salidas completas del sistema viejo guardadas como golden master.
- Fechas, identificadores y valores aleatorios congelados o fuera de las comparaciones.
- Pruebas redactadas por IA revisadas, con valores esperados tomados del sistema viejo, no del modelo.
- Cobertura revisada, y huecos llenados con entradas específicas.
- Rarezas listadas y enviadas a los dueños del negocio: mantener, corregir o retirar.
Escrito a partir del trabajo de nuestros ingenieros en sistemas en producción. ¿Quieres una segunda opinión sobre tu proyecto? Habla con un ingeniero.
Ver el trabajo →