Использование мощного STL в Go, Docker и транзакций SQL для выполнения параллельных тестов для хранилища PostgreSQL
База данных
Тестирование с использованием реальной технологии вместо тестовых даных было непростым до появления контейнеров. Для баз данных, как правило, существовал только один сервер баз данных и только одна база данных на приложение.
Mock тестирование - это общепринятое решение для тестирования взаимодействия баз данных. Mock тесты могут помочь в таких крайних случаях, как потеря соединения в середине выполнения программы. Вы можете легко начать тестирование на реальных базах данных с помощью Docker.
При нынешнем положении дел в 2022 году и с учетом доступных инструментов издевательство над базой данных похоже на тестирование кода Go путем написания интерпретатора Go.
Методологии тестирования
Я разделяю взгляды Билла Кеннеди в отношении методологии тестирования и сам не смог бы сказать об этом лучше. Я отношусь к каждому пакету как к единице кода, и когда дело доходит до тестирования единицы кода в моих проектах, моя самая большая забота - убедиться, что они работоспособны.
В этой же ветке можно найти твит:
Почему нужно тестировать на реальной базе данных?
Плюсы
- проверка правильности запросов; никаких сюрпризов в продакшене.
- быстрое выявление ошибок
- возможность составлять сложные сценарии тестов;
Минусы
- высокие затраты на управления жизненным циклом базы данных. Решено в этой статье :)
Какие инструменты нам необходимы?
- Docker
- Go
Прежде чем погрузиться в код, я предполагаю, что вы уже знакомы с Go и его мощной стандартной библиотекой. Наш код расположен в gists.
Я начну с представления результатов тестов, затем проведу вас через настройку, необходимую для выполнения тестов, и закончу реализацией тестов.
Результат
Тесты, содержащиеся в пакете ./internal/psql, выполняются параллельно с работой реальной базой данных PostgreSQL. Основным критерием здесь является время выполнения, которое составляет ~4 секунды. Время выполнения включает в себя запуск и очистку базы данных PostgreSQL, программно, с помощью go.
Перед запуском тестов пакета необходимо выполнить настройку базы данных PostgreSQL. Это делается с помощью функции TestMain и следующих внешних пакетов: psqldocker +psqltest .
Я создал скрипт psqldocker для программного управления жизненным циклом Docker-контейнеров PostgreSQL.
С помощью psqldocker.NewContainer() создается новый Docker-контейнер PostgreSQL. Программеа выполняется после запуска тестов пакета с помощью m.Run() .
Я также разработал скрипт psqltest, набор утилит для тестирования PostgreSQL, аналогичный тому, что в /net/http/httptest есть для net/http. Функция psqltest.Register() - это обертка над DATA-DOG/go-txdb/db.go:Register(), котораяпри открытии соединения с базой данных запускает это соединение в изолированной SQL-транзакции.
Запуск тестов
Поскольку каждый тест открывает новое соединение с базой данных в отдельной транзакции SQL, параллельное выполнение теста безопасно. Это позволяет разработчику работать с одним и тем же объектом базы данных в нескольких тестах, например, один и тот же объект пользователя может использоваться для нескольких тестов, которые могут изменить его состояние.
С помощью psqltest.NewTransactionTestingDB() создается новое соединение с базой данных с использованием драйвера, ранее зарегистрированного в TestMain с помощью psqltest.Register(). DSN (второй входной параметр), предоставленный sql.Open(), является именем теста, он действует как идентификатор базовой транзакции SQL. Используя один и тот же DSN, разработчик может открыть несколько подключений к базе данных для одной и той же транзакции. Например, идентификатор транзакции в первом тесте — TestUserRepository/CreateUser/Success.
Реализация psqltest.NewTransactionTestingDB():
Вывод
Итак, в этой статье я показал вам, как программно протестировать и отключить базу данных PostgreSQL с помощью Docker. Я также реализовал безопасные параллельные тесты для экземпляра базы данных, открывая соединения с базой данных в отдельных транзакциях SQL.