Testcontainers: настоящие БД и брокеры в тестах
↑ 3.6 Тестирование ASP.NET Core · ← Предыдущая · → Следующая
Зачем это на собесе
Современный стандарт интеграционных тестов: реальные 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 удаляет контейнеры даже при падении; не отключайте без необходимости.
Практика
- Замените EF InMemory на PostgreSQL в Testcontainers.
- Добавьте Kafka-контейнер и протестируйте публикацию/потребление.
- Проверьте время прогона и оптимизируйте переиспользованием контейнера.
Вопросы с ответами
Почему Testcontainers лучше InMemory?
Реальная БД воспроизводит SQL, ограничения, транзакции и миграции.
Как ускорить тесты с контейнерами?
Один контейнер на коллекцию, очистка данных вместо пересоздания, параллельность по схемам.