Una prueba de integración confiable debe poder ejecutarse muchas veces y producir el mismo resultado cuando el código no cambió. Para lograrlo, necesita controlar tres aspectos: el estado inicial, la limpieza y el aislamiento.
Estos aspectos son especialmente importantes en integración porque las pruebas suelen tocar bases de datos, archivos, colas, servicios simulados, cachés y otros recursos compartidos.
Si no controlamos el estado, una prueba puede pasar hoy, fallar mañana y volver a pasar después sin que nadie haya modificado el código. Ese tipo de prueba genera desconfianza y consume tiempo del equipo.
El estado inicial es la situación del sistema antes de ejecutar una prueba. Incluye todos los datos, configuraciones y recursos que pueden influir en el resultado.
Puede incluir:
Limpiar significa dejar los recursos usados por una prueba en un estado conocido. Puede hacerse antes de ejecutar la prueba, después de ejecutarla o en ambos momentos.
La limpieza puede consistir en:
El objetivo es evitar que una ejecución afecte a la siguiente.
Aislar pruebas significa evitar que una prueba dependa del resultado, los datos o el orden de otra prueba. Cada prueba debe preparar lo que necesita y no asumir que otra prueba se ejecutó antes.
Una prueba aislada debería poder:
El aislamiento no siempre significa usar recursos completamente separados para cada prueba, pero sí controlar las interferencias.
Algunas señales indican que las pruebas no están bien aisladas:
Cuando aparecen estas señales, el problema no siempre está en la funcionalidad probada. Muchas veces está en la preparación o limpieza del ambiente.
La limpieza puede realizarse antes de la prueba, después de la prueba o en ambos momentos. Cada enfoque tiene ventajas y riesgos.
| Momento | Ventaja | Cuidado |
|---|---|---|
| Antes de la prueba | Garantiza un inicio conocido. | Puede ocultar residuos dejados por pruebas anteriores. |
| Después de la prueba | Deja el ambiente limpio para la siguiente prueba. | Si la prueba se interrumpe, la limpieza puede no ejecutarse. |
| Antes y después | Aumenta la seguridad del aislamiento. | Puede agregar tiempo de ejecución. |
En pruebas críticas, limpiar antes y después puede ser razonable, especialmente cuando el ambiente es compartido o puede quedar en un estado inesperado.
Una estrategia común para pruebas con base de datos es ejecutar la prueba dentro de una transacción y revertirla al finalizar. Esto permite que los cambios no queden persistidos.
Ventajas:
Cuidados:
Otra estrategia es recrear la base de datos o sus tablas antes de ejecutar una suite. Esto da un punto de partida muy claro.
Puede hacerse aplicando migraciones, cargando datos semilla y luego ejecutando las pruebas.
Ventajas:
El principal costo es el tiempo de preparación. En proyectos grandes, recrear todo antes de cada prueba puede ser demasiado lento, pero hacerlo antes de la suite puede ser una buena opción.
La limpieza selectiva elimina solo los datos creados por una prueba. Para esto conviene que la prueba use identificadores claros o prefijos específicos.
Ejemplos:
test-.Esta estrategia puede ser eficiente, pero debe cuidarse para no borrar datos que otras pruebas todavía necesitan.
Los recursos compartidos son una fuente frecuente de interferencias. Una base de datos, una cola, una carpeta o un servicio simulado pueden ser usados por varias pruebas.
Para reducir problemas, conviene:
Cuanto más compartido es un recurso, más importante es controlar su estado.
Ejecutar pruebas en paralelo puede ahorrar tiempo, pero aumenta la necesidad de aislamiento. Dos pruebas que funcionan bien por separado pueden interferirse si usan los mismos datos o recursos al mismo tiempo.
Para ejecutar en paralelo, puede ser necesario:
Si la suite no está preparada para paralelismo, conviene ejecutarla de forma secuencial hasta mejorar el aislamiento.
La caché puede afectar pruebas de integración porque guarda resultados de operaciones anteriores. Si una prueba cambia datos pero la aplicación sigue leyendo un valor cacheado, el resultado puede ser incorrecto.
Conviene considerar:
La caché puede ocultar errores o producir fallas intermitentes si no se controla.
Las colas de mensajes y los eventos requieren una estrategia especial de limpieza. Un mensaje viejo puede ser consumido por una prueba nueva y generar resultados difíciles de explicar.
Buenas prácticas:
Cuando una integración usa archivos, también debe controlar rutas, nombres y limpieza. Un archivo de una ejecución anterior puede hacer que una prueba falle o pase por una razón equivocada.
Cuidados recomendados:
Supongamos una prueba que confirma una compra y descuenta stock. Para aislarla, podríamos:
| Elemento | Preparación | Limpieza |
|---|---|---|
| Usuario | Crear usuario propio de la prueba. | Eliminarlo al finalizar. |
| Producto | Crear producto con stock conocido. | Eliminar producto y movimientos de stock. |
| Orden | No debe existir antes de la prueba. | Eliminar la orden creada. |
| Pago simulado | Preparar respuesta aprobada. | Reiniciar respuestas del simulador. |
| Evento | Cola vacía antes de comenzar. | Vaciar mensajes generados. |
Al trabajar con estado inicial y limpieza, conviene evitar:
Antes de confiar en una prueba de integración, podemos revisar:
El estado inicial, la limpieza y el aislamiento son condiciones necesarias para que una suite de integración sea confiable. Sin estos cuidados, las pruebas pueden fallar por residuos, interferencias o dependencias ocultas entre casos.
Una prueba de integración valiosa no solo verifica una colaboración entre componentes; también puede repetirse en un ambiente controlado y explicar con claridad por qué pasó o falló.
En el próximo tema veremos la integración con bases de datos, uno de los casos más comunes y relevantes dentro de las pruebas de integración.