🖥 Тестирование Базы Данных
Пока кроме вашего приложения в базу данных никто не ходит, она является управляемой внепроцессной зависимостью и деталью имплементаци, а следовательно в интеграционных тестах должен использоваться настоящий экземпляр базы данных, т.е. база данных не должна заменяться моком.
Конечно, интеграционные тесты не юнит-тесты и их не так много, поэтому производительность не является ключевым критерием, однако всем нам хочется, чтобы интеграционные тесты у нас выполнялись быстро и не требовали много ресурсов (чтобы их можно было выполнять на локальной машине).
Понятно, что последовательные тесты быстрыми не бывают. А чтобы запустить тесты параллельно, их нам нужно изолировать друг от друга.
Подход №1: В лоб — одна СУБД хорошо, а X лучше
Первое, что приходит в голову, просто (не очень) поднять для каждого теста (или ряда тестов, чтобы не совсем в наглую ресурсы тратить) свой контейнер с СУБД. Делается это с помощью testcontainers, существующем для многих языков, в том числе и для го. Тесты изолированы, спокойно выполняются параллельно. Однако, далеко не каждая машина может держать одновременно огромное количество докер контейнеров, особенно, если тестов действительно много.
Подход №2: Человеческий — СУБД одна, а баз много...
Я предлагаю использовать иной подход. Говорю я применимо к PostgreSQL, однако подобные механизмы есть во всех популярных реляционных СУБД.
Что если для всех интеграционных тестов поднять одну СУБД, но для каждого отдельного теста создавать отдельную базу данных. Преимущества очевидны. Но как сделать это так, чтобы не настраивать БД перед каждым тестом. PostgreSQL позволяет вам использовать существующую базу данных в качестве шаблона при создании новой. В таком случае схема базы данных сохранится и вам не придётся выполнять десяток миграций перед каждым тестом. Т.е. я предлагаю вам с помощью testcontainers перед тестами создать один контейнер с PostgreSQL, после чего накатить на него все миграции с необходимыми таблицами. После чего с этой базой данных вы НЕ взаимодействуете, а перед каждым тестом создаёте новую, используя эталонную базу как шаблон. Вы так же можете просто руками перед тестами поднимать в докере одну СУБД, но не хотелось бы каждый раз думать об этом перед запуском тестов.
Простейший пример того, как это может выглядеть (без testcontainers) можно глянуть в репозитории: https://github.com/pantafive/demo-repository-test/blob/main/app/database_test.go#L43
Пока кроме вашего приложения в базу данных никто не ходит, она является управляемой внепроцессной зависимостью и деталью имплементаци, а следовательно в интеграционных тестах должен использоваться настоящий экземпляр базы данных, т.е. база данных не должна заменяться моком.
Конечно, интеграционные тесты не юнит-тесты и их не так много, поэтому производительность не является ключевым критерием, однако всем нам хочется, чтобы интеграционные тесты у нас выполнялись быстро и не требовали много ресурсов (чтобы их можно было выполнять на локальной машине).
Понятно, что последовательные тесты быстрыми не бывают. А чтобы запустить тесты параллельно, их нам нужно изолировать друг от друга.
Подход №1: В лоб — одна СУБД хорошо, а X лучше
Первое, что приходит в голову, просто (не очень) поднять для каждого теста (или ряда тестов, чтобы не совсем в наглую ресурсы тратить) свой контейнер с СУБД. Делается это с помощью testcontainers, существующем для многих языков, в том числе и для го. Тесты изолированы, спокойно выполняются параллельно. Однако, далеко не каждая машина может держать одновременно огромное количество докер контейнеров, особенно, если тестов действительно много.
Подход №2: Человеческий — СУБД одна, а баз много...
Я предлагаю использовать иной подход. Говорю я применимо к PostgreSQL, однако подобные механизмы есть во всех популярных реляционных СУБД.
Что если для всех интеграционных тестов поднять одну СУБД, но для каждого отдельного теста создавать отдельную базу данных. Преимущества очевидны. Но как сделать это так, чтобы не настраивать БД перед каждым тестом. PostgreSQL позволяет вам использовать существующую базу данных в качестве шаблона при создании новой. В таком случае схема базы данных сохранится и вам не придётся выполнять десяток миграций перед каждым тестом. Т.е. я предлагаю вам с помощью testcontainers перед тестами создать один контейнер с PostgreSQL, после чего накатить на него все миграции с необходимыми таблицами. После чего с этой базой данных вы НЕ взаимодействуете, а перед каждым тестом создаёте новую, используя эталонную базу как шаблон. Вы так же можете просто руками перед тестами поднимать в докере одну СУБД, но не хотелось бы каждый раз думать об этом перед запуском тестов.
Простейший пример того, как это может выглядеть (без testcontainers) можно глянуть в репозитории: https://github.com/pantafive/demo-repository-test/blob/main/app/database_test.go#L43