Imagen de una planicie como lienzo en blanco para nuestro desarrollo de software a medida

¿Qué es Testcontainers y por qué usarlo?

//Arteco - Tecnologías de la información

  • :)
  • :0
  • :D
  • ;)
  • :]
foto Ramón Arnau

Ramón Arnau

Gerente de Arteco Consulting SL

Los Testcontainers se han convertido en una herramienta esencial con Spring Boot si buscas que las pruebas sean lo más realistas posible

Testcontainers con Spring Boot: Revoluciona tus Tests de Integración

En el desarrollo de aplicaciones empresariales con Spring Boot, uno de los mayores desafíos es realizar tests de integración efectivos que incluyan bases de datos, colas de mensajes u otros servicios externos. Los Testcontainers han surgido como la solución definitiva para este problema, permitiéndonos ejecutar tests con dependencias reales en contenedores Docker efímeros.


¿Qué son los Testcontainers?

Testcontainers es una biblioteca Java que proporciona instancias ligeras y desechables de bases de datos, navegadores web, o cualquier otro servicio que pueda ejecutarse en un contenedor Docker. Estas instancias se crean específicamente para los tests y se destruyen automáticamente al finalizar, garantizando un entorno limpio y aislado para cada ejecución.


Ventajas de usar Testcontainers

1. Tests más realistas

Los tests se ejecutan contra servicios reales (PostgreSQL, MySQL, Redis, etc.) en lugar de mocks o bases de datos en memoria, proporcionando mayor confianza en el comportamiento de la aplicación.

2. Aislamiento completo

Cada test obtiene su propia instancia de base de datos, eliminando los problemas de estado compartido entre tests.

3. Configuración automática

Spring Boot detecta automáticamente los contenedores y configura las propiedades de conexión.

4. Facilidad de mantenimiento

No necesitas mantener infraestructura de testing separada ni scripts de configuración complejos.

5. Flexibilidad y soporte amplio

Se pueden levantar simultáneamente bases de datos, sistemas de mensajería, motores de búsqueda y más, incluso configurar redes internas entre contenedores.

6. Integración con CI/CD

La misma configuración funciona localmente y en pipelines de integración continua, siempre que haya Docker disponible.


Configuración inicial

Para comenzar a usar Testcontainers en tu proyecto Spring Boot, añade las siguientes dependencias a tu pom.xml:

<dependencies>
    <!-- Spring Boot Test Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
    <!-- Testcontainers PostgreSQL -->
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>postgresql</artifactId>
        <scope>test</scope>
    </dependency>
    
    <!-- Testcontainers JUnit Jupiter -->
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Implementación práctica

Ejemplo básico con PostgreSQL

@SpringBootTest
@Testcontainers
public class UserRepositoryIntegrationTest {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
            .withDatabaseName("testdb")
            .withUsername("test")
            .withPassword("test");

    @Autowired
    private UserRepository userRepository;

    @Test
    void shouldPersistAndRetrieveUser() {
        // Given
        User user = new User("Juan Pérez", "juan.perez@email.com");
        
        // When
        User savedUser = userRepository.save(user);
        User foundUser = userRepository.findById(savedUser.getId()).orElse(null);
        
        // Then
        assertThat(foundUser).isNotNull();
        assertThat(foundUser.getName()).isEqualTo("Juan Pérez");
        assertThat(foundUser.getEmail()).isEqualTo("juan.perez@email.com");
    }
}

Configuración automática con Spring Boot 3.1+

Spring Boot 3.1 introdujo soporte nativo para Testcontainers. Puedes crear una clase de configuración de test:

@TestConfiguration(proxyBeanMethods = false)
public class TestContainerConfiguration {

    @Bean
    @ServiceConnection
    PostgreSQLContainer<?> postgresContainer() {
        return new PostgreSQLContainer<>("postgres:15")
                .withReuse(true);
    }

    @Bean
    @ServiceConnection
    RedisContainer redisContainer() {
        return new RedisContainer("redis:7-alpine")
                .withReuse(true);
    }
}

Y luego usar esta configuración en tus tests:

@SpringBootTest
@Import(TestContainerConfiguration.class)
class UserServiceIntegrationTest {

    @Autowired
    private UserService userService;

    @Test
    void shouldCreateUserSuccessfully() {
        // Tu lógica de test aquí
    }
}

Casos de uso avanzados

Testing con múltiples servicios

@SpringBootTest
@Testcontainers
public class OrderProcessingIntegrationTest {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");

    @Container
    static RabbitMQContainer rabbit = new RabbitMQContainer("rabbitmq:3.11-management");

    @Container
    static RedisContainer redis = new RedisContainer("redis:7-alpine");

    @Test
    void shouldProcessOrderWithAllServices() {
        // Test que involucra base de datos, cola de mensajes y caché
    }
}

Personalización de contenedores

@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
        .withDatabaseName("orders_db")
        .withUsername("orders_user")
        .withPassword("secure_password")
        .withInitScript("init-test-data.sql")
        .withReuse(true);

Mejores prácticas

  1. Reutilización de contenedores: Usa .withReuse(true) para reducir tiempo de arranque.
  2. Contenedores estáticos: Decláralos como static para compartirlos entre todos los métodos de una clase.
  3. Configuración centralizada: Crea clases de configuración de test reutilizables.
  4. Scripts de inicialización: Usa .withInitScript() para cargar datos de prueba consistentes.
  5. Timeouts apropiados: Configura timeouts adecuados con .withStartupTimeout(Duration.ofMinutes(2)).
  6. Evita puertos fijos: Usa puertos aleatorios para facilitar paralelización.
  7. Limpieza de datos: Integra herramientas como Flyway para mantener consistencia.

Integración con CI/CD

Para usar Testcontainers en pipelines de CI/CD, asegúrate de que:

  • Docker esté disponible en el entorno de CI
  • Los runners tengan suficientes recursos
  • Configures timeouts apropiados
  • Uses registros privados de imágenes si quieres más velocidad

Ejemplo en GitHub Actions:

name: Integration Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      docker:
        image: docker:dind
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
      - name: Run integration tests
        run: ./mvnw test

Conclusión

Los Testcontainers representan un cambio de paradigma en el testing de aplicaciones Spring Boot.
Permiten crear tests de integración robustos, realistas y mantenibles sin la complejidad de mantener infraestructura separada.

En Arteco Consulting, hemos implementado Testcontainers en múltiples proyectos empresariales, observando una mejora significativa en la calidad del software y la confianza del equipo.

¿Estás listo para llevar tus tests de integración al siguiente nivel?
Los Testcontainers son la herramienta que necesitas para construir aplicaciones más robustas y confiables.


¿Necesitas ayuda implementando Testcontainers en tu proyecto? En Arteco Consulting SL somos expertos en arquitecturas de software modernas y testing avanzado. Contáctanos para una consultoría personalizada.

Mantente Conectado

Newsletter

¡Mantente al día con lo último en tecnología y negocios! Suscríbete a nuestra newsletter y recibe actualizaciones exclusivas directamente en tu correo.

Reunión Online

No dejes pasar la oportunidad de explorar nuevas posibilidades. ¡Agenda una reunión online con nosotros hoy y comencemos a construir juntos el futuro de tu negocio!

  • :D
  • :)
  • ;]
  • :0
  • :}
  • ;)
  • :>

Únete al Equipo

Contamos con una gran cartera de noveles que compaginan su formación académica con la experiencia en Arteco, aprendiendo de la mano de los que están en primera línea. Realizamos un programa intensivo de formación cara a la rápida incorporación en equipos de desarrollo reales.

Persona corriendo por el desierto representando el Team Building de Arteco Consulting
  • :)
  • :0
  • :D
  • ;)
  • :]