Выпуск Cup o' Go напомнил о пакете pgtestdb от Питера Даунса — это Go/Postgres тестовый пакет. Он построен на встроенных шаблонных базах Postgres: прямо в psql можно сделать CREATE DATABASE dbname TEMPLATE template_to_copy;. Копирование шаблона очень быстрое, быстрее миграций с нуля и уж точно быстрее тяжелых подходов на Docker. На низком уровне Postgres перечисляет отношения шаблона и копирует их файлы heap, index и каталога кусками по 8 kB.
Автор поста давно про это читал, но забыл, поэтому попросил Codex встроить pgtestdb в тестовый набор River и сравнить с текущим подходом. River использует собственные хелперы, которые изолируют тест-кейсы по схемам. Это медленнее, чем test transactions, зато оставляет состояние теста для разбора падений, позволяет проверять фичи уровня базы вроде listen/notify и граничные случаи с несколькими транзакциями и откатами. Схема в Postgres легче базы, но её нельзя клонировать, поэтому каждый раз приходится гонять миграции. У pgtestdb тут преимущество.
Сравнение setup-времени вышло почти одинаковым: для 466 клонов pgtestdb среднее — 98.4ms, p90 — 247.4ms, p95 — 299.5ms, максимум — 465.1ms. Для 81 создания схемы с миграцией — 99.4ms, p90 — 152.1ms, p95 — 209.0ms, максимум — 327.0ms. То есть обе методики укладываются примерно в 100ms. Автор удивился: он всегда считал создание новых баз медленным.
Тут он признаёт, что немного лукавил: хотя setup-время почти одинаковое, полный wall time с pgtestdb — 51.07s, а со схемами — 14.54s, примерно в 3.5 раза быстрее. Дело не в том, что схемы сами по себе сильно быстрее. Хелперы River создают столько тестовых схем, сколько нужно для мгновенной параллелизации Go, и держат их в пуле: если есть свободная схема, тест-кейс чистит и переиспользует её вместо создания с нуля. Это требует аккуратности, например схемы можно переиспользовать только на той же версии. Механизм автор писал ещё до LLM и несколько дней вылавливал баги.
Переиспользование можно прикрутить и к pgtestdb — внутри пакета или как надстройку в вызывающих проектах. 100ms на подъём тестовой базы неплохо, но для приложения с 10 000 тестами хочется setup на порядок быстрее. Переиспользование снижает время до 10–20ms, что уже ближе к test transactions. В тестах River текущий метод со схемами останется: он быстрый, а изоляция по схемам заодно проверяет, что schema-based configuration работает как заявлено. Зато в документации River появится рекомендация pgtestdb, особенно для end-to-end тестов — от вставки задачи клиентом до её полного выполнения воркером.