Testcontainers: настоящие БД и брокеры в тестах

↑ 3.6 Тестирование ASP.NET Core · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Современный стандарт интеграционных тестов: реальные PostgreSQL/Kafka в Docker вместо in-memory заглушек.

Объяснение

Testcontainers поднимает Docker-контейнеры на время тестов.

public class DbFixture : IAsyncLifetime
{
    private readonly PostgreSqlContainer _pg = new PostgreSqlBuilder().WithImage("postgres:16").Build();
    public string ConnectionString => _pg.GetConnectionString();
 
    public Task InitializeAsync() => _pg.StartAsync();
    public Task DisposeAsync() => _pg.DisposeAsync().AsTask();
}
 
public class ApiFactory(DbFixture db) : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder b) =>
        b.UseSetting("ConnectionStrings:Default", db.ConnectionString);
}
ПодходПлюсыМинусы
EF InMemoryбыстродругое поведение, нет SQL/транзакций/ограничений
SQLite in-memoryлучшедиалект отличается от прод
Testcontainersреальное поведениенужен Docker, дольше старт

Готовые модули: PostgreSql, MsSql, MongoDb, Redis, Kafka, RabbitMq, MinIO, Keycloak.

Нюансы и подводные камни

  • Один контейнер на набор тестов (collection fixture), а не на тест.
  • В CI нужен Docker (GitHub Actions поддерживает из коробки).
  • Применяйте миграции при старте фикстуры.
  • Порты случайные: берите строку подключения из контейнера.
  • Ryuk удаляет контейнеры даже при падении; не отключайте без необходимости.

Практика

  1. Замените EF InMemory на PostgreSQL в Testcontainers.
  2. Добавьте Kafka-контейнер и протестируйте публикацию/потребление.
  3. Проверьте время прогона и оптимизируйте переиспользованием контейнера.

Вопросы с ответами

Связанные темы