Модульное тестирование с сервером БД, работающим в докере, является гораздо лучшим выбором, чем Sqlmock, обычно
Около двух лет назад я написал статью, обсуждающую, как тестировать приложение GORM с помощью Sqlmock.
Время летит незаметно, и я понимаю, что большинство разработчиков не принимают такой подход (по крайней мере, в моей команде). Написание тестового примера с использованием Sqlmock слишком сложно для начала.
Основная проблема заключается в том, что вам нужно написать весь фрагмент SQL вручную, а затем сравнить его с выводом GORM. Эта рабочая нагрузка уже намного больше, чем написание кодов для тестирования. В конце концов, причина, по которой мы используем GORM, заключается в том, чтобы не писать необработанный SQL вручную.
Нам нужно найти лучший способ.
Улучшить процесс модульного тестирования
В общем, тестировать приложение БД сложно. Основная причина — сам сервер базы данных.
- Если команда разработчиков использует удаленный сервер базы данных, конфликт данных неизбежен.
- Если мы создадим учетные записи для каждого разработчика на этом сервере базы данных, то модульные тесты должны запускаться с разными учетными записями. И кто-то должен вести эти учетные записи.
- Если мы потребуем, чтобы каждый разработчик установил и настроил сервер базы данных на своей локальной рабочей станции, мы усложним настройку среды разработки.
Кажется, нет ответа достаточно хорошо. Но если бы мы могли запустить сервер базы данных локально с помощью докера и интегрировать тестовый пример с помощью докера, это было бы идеально.
Процесс изображения ниже:
- Запустите сервер базы данных с докером перед каждым набором тестов. открыть соединение GORM с этим сервером
- Перед запуском каждого тестового случая очищайте данные в базе данных и при необходимости заново создавайте таблицы.
- Запустите все тестовые случаи
- Остановить сервер базы данных после выполнения набора тестов
Теоретически мы могли бы управлять демоном docker с помощью командной строки. Но с помощью dockertest эта цель может быть легко достигнута.
Модульное тестирование сервера базы данных в Docker
Вот пошаговое руководство по модульному тестированию приложения GORM с реальным сервером базы данных, работающим в докере.
мы повторно используем пример приложения из предыдущей статьи. Вы можете найти исходный код на Github.
В качестве примера в этой статье мы используем Postgres, но он может работать и с любой другой базой данных.
Настройка набора тестов
Согласно схеме последовательности делаем ряд заготовок:
- В
BeforeSuite
мы создаем экземпляр*gorm.DB
и функцию для очистки ресурсов докера. ФункцияsetupGormWithDocker
будет объяснена позже. - В
AfterSuite
мы вызываемcleanupDocker
для освобождения ресурсов, связанных с докером. - В
BeforeEach
мы удаляем схему по умолчанию, а затем создаем ее заново, чтобы убедиться, что база данных чиста и готова перед каждым запуском тестового примера.
Ниже приведены пояснения к основной функции setupGormWithDocker
:
- Создайте пул ресурсов докеров с
dockertest.NewPool
, который используется для запуска контейнера докеров. - Укажите имя образа, версию образа и переменную среды с помощью
dockertest.RunOptions
. fnConfig
— это функция для управления политикой начальной загрузки. В этом случае нам нужно, чтобы docker-контейнер автоматически удалялся после остановки и никогда не перезапускался автоматически.- Мы используем
pool.RunWithOptions
для запуска контейнера, затем создаем функцию очисткиfnCleanup.
- Так как запуск контейнера займет некоторое время, нам нужно дождаться готовности контейнера. Только после этого мы можем вернуть экземпляр
*gorm.DB
. Здесь на помощь приходитpool.Retry
.pool.Retry
будет многократно выполнять функцию параметра, пока функция не вернетnil
(что означает, что контейнер готов)
Создание тестового примера
С подготовкой в наборе тестов мы могли бы получить пригодный для использования экземпляр *gorm.DB
, подключающийся к локальному серверу базы данных, и база данных будет очищаться перед каждым выполнением тестового примера.
- В
BeforeEach
мы создаем экземплярRepository
для тестирования. Вызовrepo.Migrate
для автоматического создания таблиц, а затем создания образца данных блога. - Тестовые случаи довольно интуитивны. Мы вызываем методы репо и проверяем, что ожидаемый результат возвращается. Здесь нет никакой имитации, так как мы используем настоящий сервер базы данных.
- По сравнению с Sqlmock, нет необходимости писать необработанный SQL вручную, и мы можем завершить весь тестовый пример менее чем за сотню строк кода.
Другие важные примечания
- dockertest будет извлекать образы, если это необходимо, но без подсказки о ходе загрузки. Мы предлагаем запустить
docker pull postgres:14
перед первым запуском тестового примера. - Запуск набора тестов может занять несколько секунд, так как нам нужно запустить сервер базы данных Postgres. Это может показаться медленнее, чем большинство модульных тестов в памяти, но это приемлемо.
- Во время
pool.Retry
будут выводиться некоторые ошибки соединения. Если вам не нравятся помехи, передайте&gorm.Config{Logger: logger.Default.LogMode(logger.Silent)}
вgorm.Open
, чтобы закрыть журнал - Ваше приложение может зависеть от некоторого расширения Postgres. В этом случае вы можете заменить стандартный образ Postgres на пользовательский. Например, если вам нужно постгрес все, вы можете использовать этот образ докера.
Заключение
- Тестирование приложения GORM на реальном сервере базы данных имеет огромное преимущество.
- С помощью
dockertest
локальный докер-контейнер может беспрепятственно работать с модульным тестированием Golang. - В отличие от
Sqlmock
, вся логика БД работает на реальном сервере БД, никаких моков не нужно, а тестовые случаи значительно упрощены. - Есть ли какая-то причина придерживаться Sqlmock сейчас?
- Для получения полного исходного кода посетите его репозиторий.
Ваше здоровье!
Ресурсы
Как выполнить модульное тестирование приложения GORM с помощью Sqlmock.
Want to Connect? Follow me on Twitter.