Testes de Integração C# com Docker: Técnicas Avançadas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Testes de Integração C# com Docker: Nível Avançado



Testes de integração são uma etapa criticamente importante no desenvolvimento em C#, permitindo verificar a interação dos componentes do sistema com dependências reais: bancos de dados, filas de mensagens, APIs externas. O uso do Docker para esse fim tornou-se um padrão da indústria, mas em nível avançado surgem questões de isolamento, desempenho e execução paralela. Neste artigo, abordaremos técnicas profissionais de testes de integração C# com Docker, utilizando a biblioteca Testcontainers e configurações avançadas.



1. Configuração do Testcontainers para .NET: Infraestrutura Básica



A biblioteca Testcontainers para .NET permite gerenciar programaticamente contêineres Docker no ambiente de teste. Diferentemente da execução manual do docker-compose, o Testcontainers inicia e para automaticamente os contêineres para cada classe de teste ou módulo, garantindo um ambiente limpo.



Instale o pacote via NuGet:

dotnet add package Testcontainers --version 3.9.0dotnet add package Testcontainers.PostgreSql --version 3.9.0dotnet add package Testcontainers.MsSql --version 3.9.0


Exemplo de classe base para testes de integração com PostgreSQL:

using Testcontainers.PostgreSql;using Xunit;

public class DatabaseFixture : IAsyncLifetime{ private readonly PostgreSqlContainer _container = new PostgreSqlBuilder() .WithImage("postgres:15-alpine") .WithDatabase("testdb") .WithUsername("testuser") .WithPassword("testpass") .Build();

public string ConnectionString => _container.GetConnectionString();

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

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


Agora, cada classe de teste pode usar essa fixture para obter uma instância isolada do banco de dados.



2. Isolamento de Testes e Gerenciamento de Estado dos Contêineres



O nível avançado exige controle refinado sobre o isolamento. Em vez de um contêiner para todo o conjunto de testes, use um contêiner por classe de teste ou até mesmo por teste. Isso evita o estado "sujo" do banco de dados entre os testes.



Implementação usando o atributo Collection no xUnit:

[CollectionDefinition("Database collection")]public class DatabaseCollection : ICollectionFixture<DatabaseFixture>{}

[Collection("Database collection")]public class UserRepositoryTests{ private readonly DatabaseFixture _fixture;

public UserRepositoryTests(DatabaseFixture fixture) { _fixture = fixture; }

[Fact] public async Task CreateUser_ShouldPersistUser() { // Arrange await using var context = new AppDbContext(_fixture.ConnectionString); await context.Database.EnsureCreatedAsync(); var repo = new UserRepository(context);

// Act var user = new User { Name = "Test User" }; await repo.CreateAsync(user);

// Assert var savedUser = await context.Users.FindAsync(user.Id); Assert.NotNull(savedUser); }}


Para isolamento total no nível do teste, use ITestOutputHelper e crie o contêiner dentro do método DisposeAsync:

public class IsolatedTest : IAsyncLifetime{    private PostgreSqlContainer _container;

public async Task InitializeAsync() { _container = new PostgreSqlBuilder().Build(); await _container.StartAsync(); }

public async Task DisposeAsync() { await _container.DisposeAsync(); }}


3. Execução Paralela de Testes e Gerenciamento de Recursos



Um dos principais

Blogs

Book Recommendations