Saltar al contenido
SDETRole
SDETRole

Glosario · CI/CD y DevOps

Testcontainers

También llamado: Testcontainers for Java, testcontainers-node, test containers

Definición

Librería que arranca dependencias reales, como bases de datos, brokers o navegadores, en contenedores Docker desechables desde tu código de test y luego los elimina.

Testcontainers es una librería de código abierto, disponible para Java, Node.js, .NET, Go, Python y otros lenguajes, que controla Docker desde dentro de tus tests. Un test pide “una base de datos Postgres 16”, la librería arranca un contenedor, espera a que esté listo, te da los datos de conexión y elimina el contenedor cuando el test termina. Pruebas contra el motor de base de datos real en lugar de contra un sustituto en memoria o un entorno compartido.

Ejemplo (Testcontainers para Java 1.x, JUnit 5)

import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

import static org.junit.jupiter.api.Assertions.assertTrue;

@Testcontainers
class DatabaseIT {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @Test
    void canQueryTheDatabase() throws Exception {
        try (Connection conn = DriverManager.getConnection(
                postgres.getJdbcUrl(), postgres.getUsername(), postgres.getPassword());
             ResultSet rs = conn.createStatement().executeQuery("SELECT 1")) {
            assertTrue(rs.next());
        }
    }
}

Un campo static comparte un único contenedor entre todos los tests de la clase; un campo de instancia arrancaría uno nuevo por test. En una suite real apuntarías tu repositorio o tu contexto de Spring a getJdbcUrl() y ejecutarías antes las migraciones.

Por qué importa

Los tests de integración contra H2 o SQLite a menudo pasan mientras la base de datos de producción rechaza el mismo SQL, porque difieren los dialectos, las restricciones y el comportamiento de las transacciones. Testcontainers te da el motor real casi con la comodidad de un mock, y cada ejecución parte de un estado limpio, lo que elimina la inestabilidad (flakiness) por datos compartidos.

Lo que conviene saber

  • Necesita un runtime compatible con Docker en la máquina y en los runners de CI. Los runners Ubuntu alojados por GitHub tienen Docker disponible.
  • Arrancar un contenedor cuesta segundos. Comparte contenedores por clase o por suite y reinicia los datos entre tests en lugar de reiniciar el contenedor.
  • Fija las versiones de las imágenes para que coincidan con producción.
  • Existen módulos listos para servicios comunes (Postgres, MySQL, Kafka, LocalStack, Selenium y más), y GenericContainer cubre cualquier otra imagen.
  • Complementa a los test doubles en lugar de sustituirlos: los tests unitarios deben seguir ejecutándose en memoria y siendo rápidos.

Escribe para buscar en todo SDETRole.

Búsqueda de texto completo con Pagefind · se ejecuta en tu navegador Abrir la página de búsqueda →