Las pruebas de integración se concentran en los puntos donde los componentes se conectan. Para probar bien esos puntos, necesitamos entender tres ideas: interfaces, contratos y responsabilidades.
La interfaz define cómo se comunican las partes. El contrato define qué acuerdos deben respetar. La responsabilidad define qué debe hacer cada componente y qué no debería hacer.
Cuando estas tres ideas están claras, las pruebas de integración son más precisas. Cuando están confusas, las pruebas tienden a ser frágiles, incompletas o difíciles de diagnosticar.
Una interfaz es el punto de contacto entre dos componentes. Es el medio por el cual un componente solicita algo, entrega información o recibe una respuesta.
Una interfaz puede tomar distintas formas:
En pruebas de integración, no solo importa que la interfaz exista. También importa que se use de acuerdo con lo esperado.
Un contrato es el conjunto de reglas que una interfaz debe cumplir para que los componentes puedan colaborar. Puede estar documentado formalmente o estar implícito en el código y en los casos de uso.
Un contrato puede especificar:
La responsabilidad de un componente es aquello que le corresponde hacer dentro del sistema. Definir responsabilidades evita duplicaciones, confusiones y acoplamientos innecesarios.
Por ejemplo, en una aplicación con capas:
Cuando un componente asume responsabilidades que no le corresponden, las integraciones se vuelven más difíciles de probar y mantener.
Estas tres ideas están conectadas. Una responsabilidad suele exponerse mediante una interfaz, y esa interfaz necesita un contrato para ser usada correctamente.
Por ejemplo, un servicio de usuarios puede tener la responsabilidad de registrar nuevos usuarios. Su interfaz puede ser una operación llamada crearUsuario. Su contrato puede indicar que necesita nombre, correo y contraseña, y que debe rechazar correos duplicados.
Una prueba de integración puede verificar que otro componente use esa interfaz respetando el contrato y que el servicio cumpla su responsabilidad.
En muchas integraciones podemos identificar un productor y un consumidor. El productor entrega datos o comportamiento; el consumidor los usa.
| Situación | Productor | Consumidor |
|---|---|---|
| Un servicio consulta una base de datos. | Base de datos. | Servicio. |
| Un controlador llama a un servicio. | Servicio. | Controlador. |
| Una API devuelve información de clientes. | API. | Cliente de la API. |
| Un proceso publica un evento. | Proceso publicador. | Proceso consumidor. |
Las fallas aparecen cuando el productor entrega algo distinto de lo esperado o cuando el consumidor interpreta mal lo recibido.
Un contrato de entrada define qué debe recibir un componente para poder trabajar correctamente. Si la entrada no cumple el contrato, el componente debería rechazarla o manejarla de forma controlada.
Al probar integraciones, conviene revisar:
Una integración robusta no debe depender de entradas perfectas. También debe comportarse bien ante entradas inválidas o incompletas.
Un contrato de salida define qué devuelve o produce un componente después de ejecutar una operación. Puede ser una respuesta, un registro guardado, un archivo, un mensaje o un cambio de estado.
La prueba de integración puede verificar que la salida incluya:
El contrato de salida es tan importante como el de entrada, porque otros componentes suelen depender de esa respuesta para continuar el flujo.
Cuando cada componente tiene una responsabilidad clara, las integraciones son más simples de probar. Sabemos qué debe preparar un componente, qué debe delegar y qué resultado debe esperar.
En cambio, si las responsabilidades se mezclan, aparecen problemas como:
Las pruebas de integración pueden revelar estos problemas, porque muestran cómo se comporta el sistema cuando las responsabilidades se combinan.
Supongamos una funcionalidad para registrar usuarios. Podemos dividir responsabilidades así:
| Componente | Responsabilidad | Contrato relevante |
|---|---|---|
| Controlador | Recibir la solicitud y devolver una respuesta. | Debe recibir nombre, correo y contraseña. |
| Servicio de usuarios | Aplicar reglas de registro. | Debe rechazar correos duplicados y contraseñas inválidas. |
| Repositorio | Guardar y consultar usuarios. | Debe persistir los campos requeridos sin perder información. |
| Servicio de correo | Enviar mensaje de bienvenida. | Debe recibir correo, asunto y contenido. |
Una prueba de integración puede verificar que estos componentes colaboren correctamente cuando se registra un usuario válido y también cuando se intenta registrar un correo duplicado.
Los contratos cambian con el tiempo. Se agregan campos, se modifican reglas, se eliminan respuestas antiguas o se ajustan formatos. Cada cambio puede afectar a los consumidores.
Un cambio de contrato puede romper una integración aunque el componente modificado siga pasando sus pruebas internas. Por ejemplo, un servicio puede empezar a devolver un nuevo estado llamado pendiente_revision, pero el consumidor solo conoce activo e inactivo.
Las pruebas de integración ayudan a detectar estos impactos. Cuando un contrato cambia, conviene revisar qué pruebas deben actualizarse y qué consumidores pueden verse afectados.
No todos los contratos están escritos. A veces el acuerdo vive solo en el código, en comentarios, en ejemplos o en conocimiento del equipo. Estos contratos implícitos son riesgosos porque pueden interpretarse de distintas formas.
Señales de contratos implícitos:
0 o null, tiene un significado no explicado.Una prueba de integración puede convertir parte de ese conocimiento en una verificación concreta y repetible.
Al probar interfaces y contratos, buscamos detectar problemas como:
Estos errores no siempre producen una falla inmediata. A veces generan datos incorrectos o comportamientos inconsistentes que se descubren más tarde.
Una prueba de integración debe dejar claro qué contrato está verificando. Para eso conviene que el caso de prueba indique:
Por ejemplo, en lugar de escribir una prueba llamada “probar usuario”, es más claro usar un objetivo como “registrar usuario válido debe guardar el usuario y enviar confirmación”.
Al trabajar con interfaces, contratos y responsabilidades, conviene aplicar algunas buenas prácticas:
Las interfaces, los contratos y las responsabilidades son la base de una integración comprensible. Cuando están bien definidos, el equipo puede probar colaboraciones con mayor precisión y diagnosticar fallas con menos esfuerzo.
Una buena prueba de integración no solo ejecuta componentes juntos: verifica que cada parte respete el acuerdo que permite que el conjunto funcione.
En el próximo tema analizaremos los límites del sistema: qué incluir y qué dejar fuera de una prueba de integración.