Pruebas de integración de C# con Docker: guía completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Pruebas de Integración en C# con Docker: Cómo Eliminar los Problemas de Entorno



Todo desarrollador de C# ha enfrentado esta situación: las pruebas pasan en la máquina local pero fallan en el servidor de CI. La razón suele ser diferencias en el entorno: versión de base de datos, configuración de Redis, servicios de prueba faltantes. Las pruebas de integración en C# con Docker resuelven este problema de una vez por todas. En este artículo, veremos cómo configurar un entorno de prueba aislado usando contenedores, escribir pruebas de integración reales e integrarlas en un pipeline de CI/CD.



Por qué Docker es la Herramienta Perfecta para Pruebas de Integración en C#



Las pruebas de integración verifican la interacción entre componentes del sistema: aplicación + base de datos, API + caché, microservicios entre sí. Sin Docker, tendrías que:

  • Instalar PostgreSQL, SQL Server, Redis en cada máquina de desarrollo
  • Configurar el servidor de CI con las mismas versiones
  • Limpiar datos entre ejecuciones de pruebas

Docker resuelve todas estas tareas. Describes la infraestructura en código (Dockerfile, docker-compose.yml) y se despliega de manera idéntica en cualquier sistema. Para C# (.NET) esto es especialmente relevante ya que Microsoft apoya activamente la contenerización: imágenes oficiales de .NET SDK, SQL Server en un contenedor Linux, integración con Azure DevOps.



Configuración del Proyecto: Testcontainers + xUnit



Para las pruebas de integración en C# con Docker, usaremos la librería Testcontainers (disponible en NuGet). Gestiona automáticamente el ciclo de vida del contenedor: se inicia antes de las pruebas, se detiene al finalizar.



Paso 1. Instalación de Paquetes



Crea un nuevo proyecto para pruebas o abre uno existente. Agrega los paquetes NuGet:

dotnet add package Testcontainersdotnet add package Testcontainers.PostgreSqldotnet add package xunitdotnet add package FluentAssertions


Paso 2. Clase Base para Pruebas con Contenedores



Creemos una clase abstracta que inicie PostgreSQL antes de ejecutar las pruebas:

using Testcontainers.PostgreSql;using Xunit;

public abstract class IntegrationTestBase : IAsyncLifetime{ private readonly PostgreSqlContainer _postgresContainer;

protected string ConnectionString => _postgresContainer.GetConnectionString();

protected IntegrationTestBase() { _postgresContainer = new PostgreSqlBuilder() .WithImage("postgres:15-alpine") .WithDatabase("testdb") .WithUsername("test") .WithPassword("test123") .Build(); }

public async Task InitializeAsync() { await _postgresContainer.StartAsync(); }

public async Task DisposeAsync() { await _postgresContainer.StopAsync(); }}

La clase implementa IAsyncLifetime de xUnit — el contenedor se iniciará antes de la primera prueba y se detendrá después de la última. El método GetConnectionString() devuelve el puerto dinámico que Docker asignó al contenedor.



Paso 3. Escribiendo una Prueba de Integración



Ahora escribamos una prueba que verifique el trabajo del repositorio con una base de datos real:

public class UserRepositoryTests : IntegrationTestBase{    [Fact]    public async Task CreateUser_Should_SaveToDatabase()    {        // Arrange        await using var connection = new NpgsqlConnection(ConnectionString);        await connection.OpenAsync();                var repository = new UserRepository(connection);        var user = new User { Name = "Ivan", Email = "ivan@example.com" };

// Act var userId = await repository.CreateAsync(user);

// Assert userId.Should().BeGreaterThan(0); var savedUser = await repository.GetByIdAsync(userId); savedUser.Should().NotBeNull(); savedUser.Name.Sho

Blogs

Book Recommendations