Testcontainers для PostgreSQL и ClickHouse

↑ 4.3 Тестирование слоя данных · ← Предыдущая · → Следующая

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

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

Практическая реализация «тестов на настоящей БД» в CI.

Объяснение

public class PgFixture : IAsyncLifetime
{
    private readonly PostgreSqlContainer _pg = new PostgreSqlBuilder()
        .WithImage("postgres:16-alpine").WithDatabase("test").Build();
 
    public string ConnectionString => _pg.GetConnectionString();
 
    public async Task InitializeAsync()
    {
        await _pg.StartAsync();
        await using var db = CreateContext();
        await db.Database.MigrateAsync();   // реальные миграции проверяются тоже
    }
 
    public Task DisposeAsync() => _pg.DisposeAsync().AsTask();
    public AppDbContext CreateContext() => new(new DbContextOptionsBuilder<AppDbContext>().UseNpgsql(ConnectionString).Options);
}
 
[CollectionDefinition("db")] public class DbCollection : ICollectionFixture<PgFixture> { }

ClickHouse: new ClickHouseBuilder().WithImage("clickhouse/clickhouse-server:24").Build(), схема создаётся SQL-скриптом при старте.

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

  • Один контейнер на коллекцию; не запускайте контейнер на каждый тест.
  • В CI нужен доступ к Docker-демону (GitHub Actions: доступен по умолчанию).
  • Фиксируйте версию образа как в продакшене.
  • Порты случайны: используйте GetConnectionString().
  • Кэшируйте образы в CI, чтобы не тратить время на pull.

Практика

  1. Поднимите PostgreSQL через Testcontainers и прогоните миграции.
  2. Добавьте ClickHouse и протестируйте вставку батча.
  3. Замерьте время старта и подберите стратегию переиспользования.

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

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