Capturar correo en pruebas consiste en desviar los mensajes que genera el sistema hacia un destino que controlas por completo, en lugar de dejarlos salir hacia un servicio de correo real. El cambio parece pequeño y altera por completo la estabilidad de una suite de integración continua: menos esperas, menos fallos intermitentes y ningún dato que se escape del entorno.
Por qué la integración continua no debería depender del correo real
Una prueba que envía correo a un servicio externo depende de demasiadas cosas que no controla. Depende de que la red funcione, de que el proveedor responda, de que la dirección siga siendo válida y de que la entrega ocurra dentro del tiempo que la prueba está dispuesta a esperar. Cualquiera de esas condiciones puede fallar por motivos ajenos al código que se está probando.
El resultado es una suite que falla de vez en cuando sin que nadie haya cambiado nada. Esos fallos intermitentes son caros: consumen tiempo de investigación, erosionan la confianza en las pruebas y acaban enseñando al equipo a ignorar los avisos.
Hay además una razón de privacidad. Si el entorno de integración escribe en buzones reales, cada ejecución deja rastro de datos de prueba en sistemas de terceros, y ese rastro se acumula con cada compilación.
¿Cómo se captura un mensaje dentro del propio entorno?
La forma más directa es apuntar el envío hacia un receptor que corre junto a la aplicación, en el mismo entorno de pruebas. Ese receptor acepta la conexión, guarda el mensaje y lo deja disponible para que la prueba lo lea. La aplicación no sabe que está en un entorno simulado; simplemente entrega como siempre.
También es posible trabajar sin red en absoluto, interceptando la llamada en el propio código o en la capa de configuración del envío, de modo que el mensaje se deposite en memoria. Esta variante es la más rápida y la más determinista, aunque exige que la prueba tenga acceso al contenido desde el mismo proceso.
En ambos casos el principio es idéntico: el mensaje no sale del entorno, y la prueba lo consulta donde se quedó.
Qué gana una prueba que lee el mensaje sin salir del proceso
La primera ventaja es la velocidad. No hay que atravesar una red externa ni esperar a que un proveedor procese la cola, así que el tiempo de la prueba baja y la suite completa se vuelve más llevadera.
La segunda es el determinismo. Si el mensaje se guarda en un lugar conocido, la prueba puede comprobar su contenido exacto —el asunto, el enlace, la cifra que debería aparecer— en lugar de limitarse a confirmar que algo llegó.
La tercera es que el entorno se vuelve autónomo. Las pruebas se pueden ejecutar sin conexión, en un contenedor aislado y sin credenciales de ningún servicio de correo, lo que simplifica mucho la configuración de una máquina nueva.
Aislar direcciones, procesos y ejecuciones
Compartir un único buzón entre todas las pruebas es la manera más rápida de crear fallos difíciles de explicar. Dos casos que se ejecutan a la vez entregan sus mensajes en el mismo sitio, y cada uno puede leer el que no le corresponde.
La solución habitual es generar una dirección distinta por caso de prueba y buscarla por su valor exacto. Así, aunque el receptor sea compartido, cada prueba sabe cuál de los mensajes es suyo.
Conviene además pensar en las ejecuciones paralelas. Si varios procesos comparten el mismo receptor en memoria, la prueba debe poder distinguir sus mensajes por destinatario y no por orden de llegada. El orden nunca es una garantía en un sistema de correo.
¿Cuándo sí conviene probar contra un servidor de verdad?
Hay dos situaciones en las que merece la pena salir del entorno simulado y hablar con un servicio real. La primera es cuando lo que se quiere verificar es precisamente la configuración de envío: que el dominio esté bien autorizado y que los mensajes no acaben en la carpeta de correo no deseado.
La segunda es la comprobación manual antes de un lanzamiento importante, con un envío real a un buzón que alguien vaya a mirar. Esas pruebas detectan problemas de reputación y de formato que un receptor local nunca revelaría.
Lo importante es que estas comprobaciones sean pocas, deliberadas y separadas de la suite rápida, para que un fallo del proveedor no bloquee cada cambio de código.
Un buzón desechable para las comprobaciones manuales
Mientras la suite automática lee los mensajes en memoria, la comprobación humana necesita un buzón de verdad sin ensuciar el correo de nadie. En el buzón de correo temporal de este sitio se crea una dirección al momento y se ve llegar el mensaje sin configurar nada.
Si el objetivo es revisar los textos y no el mecanismo, la guía sobre pruebas de correo transaccional propone una lista de comprobaciones que se aplica bien sobre esos mensajes de prueba.
Notas para quien programa
- Apunta el envío a un destino del propio entorno por configuración, no cambiando el código del producto. La prueba no debería introducir ramas que solo existen en el entorno de pruebas.
- Da a cada caso su propia dirección y busca por ese valor, nunca por el mensaje más reciente.
- Comprueba el contenido, no solo la llegada. Un mensaje vacío también se entrega.
- Guarda el mensaje completo cuando una prueba falla. El cuerpo original resuelve en segundos lo que de otro modo exige volver a reproducir el escenario.
- No esperes un número fijo de segundos. Sondea hasta que el mensaje aparezca y falla con un límite explícito.
- Deja las pruebas contra servicios reales en un grupo aparte, que se ejecute cuando alguien lo pida.
Siguientes pasos
Elige una prueba de tu suite que hoy dependa del correo externo y cámbiala para que lea el mensaje dentro del entorno. Si el resultado es más rápido y no falla al repetirla varias veces, ya tienes el argumento para extender el cambio al resto.
Para el escenario en el que el mensaje se lee desde una prueba de extremo a extremo, la guía sobre códigos de un solo uso en pruebas automáticas desarrolla la parte de extraer el código.
Lo que se captura en el entorno de integración son mensajes de prueba: no son credenciales ni identidades de nadie, y no deben usarse fuera del laboratorio.