Перейти на тестирование
Интеграционный тест Golang с MySQL
Тест интеграции с testify Suite, уверен, он вам понадобится ...
Когда вы создаете приложение go и развертываете его без тестирования, вы часто обнаруживаете ошибку в своем коде. Не рекомендуется развертывать непроверенный код. Обычно в веб-разработке существует 3 типа тестирования:
- Модульное тестирование - это тестирование самых маленьких модулей по отдельности, или мы можем сказать, что мы тестируем каждую функцию. Обычно тестируется разработчиком или CI (непрерывная интеграция), это самый дешевый и простой из трех тестов. Объем этого теста довольно велик.
- Интеграционный тест отвечает за объединение некоторых разделов нашего приложения, которые являются частью потока нашей программы, и за обеспечение правильного взаимодействия между разделами. Например, поток регистрации пользователей. Пользователи не могут зарегистрировать 2 повторяющихся письма и т. Д.
- Функциональный тест - это последний тест перед развертыванием кода в реальной среде, это работа по обеспечению качества и, конечно же, этот тест стоит больше всего денег и времени.
В этой статье мы протестируем Integration Test с нашим кодом базы данных Go-MySQL.
Требование
- Github.com/gin-gonic/gin (необязательно)
- Github.com/stretchr/testify
- Gorm.io/gorm
- Github.com/google/uuid (необязательно)
Достаточно некоторых основ программирования на Go. Для маршрутизатора http вы можете использовать net/http
, я предпочитаю gin
из-за функции.
Мы будем использовать testify, чтобы помочь нам с тестированием позже, а GORM - это библиотека go-ORM для базы данных SQL, которая поможет нам с запросом к базе данных.
Репозиторий: https://github.com/david-yappeter/go-mysql-suite
Начать
Инициализируйте модуль go.
$ mkdir go-mysql-suite && cd go-mysql-suite && go mod init myapp
Каталог и файлы нашего проекта в итоге будут выглядеть так.
. ├── config │ └── gorm.go ├── controllers │ └── user.go ├── entity │ └── user.go └── migrations │ ├── migration.go ├── service │ └── user.go └── tests │ ├── suite_test.go │ └── user_test.go ├── .env ├── go.mod ├── go.sum └── server.go
Сначала напишем наш server.go
server.go
func init()
будет вызываться первым перед main()
start, он загрузит .env
config, когда мы запустим программу. Затем мы вызываем config.ConnectGorm()
, чтобы инициализировать соединение с базой данных, мы напишем код позже, и мы вызываем defer sqlDB.Close()
, чтобы закрыть соединение с базой данных после остановки нашего кода.
Здесь мы предоставим 2 основных конечных точки: /users (GET), /users (POST)
, первая - для получения массива пользователей, а вторая - для создания пользователя. Контроллер будет инициализирован позже внутри controllers/user.go
.
Далее мы перейдем к config/gorm.go
config/gorm.go
В этом файле мы инициализируем глобальную переменную db *gorm.DB
, в которой хранится наш пул базы данных, и ConnectGorm()
вызывается в server.go
и присваивает значение db
при выполнении кода. Нашим получателем будет GetDB()
, который вернет значение db
.
Остальные функции initConfig(), initLog(), initNamingStrategy
- это просто конфиг GORM.
Затем мы создадим нашу User
сущность в entity/user.go
entity/user.go
Мы создадим простого пользователя, чтобы сделать CRUD короче. Тег binding
предназначен для gin
связующего позже, а тег gorm
поможет нам при миграции модели.
Перейдем к controllers
controller/user.go
В нашем контроллере User
есть глобальная переменная UserController
, которая будет вызываться в server.go
и содержать 2 функции Create
и GetAll
. Функция будет получать / создавать пользовательские данные из модуля service
, который мы создадим позже.
Для service
мы создадим 3 функции UserCreate
, UserGetAll
, UserGetByEmail
service/user.go
Мы будем использовать github.com/google/uuid
для хеширования user.ID
при вставке данных в базу данных, а UserGetAll
вернет всех пользователей из базы данных. И, конечно же, нам нужно будет проверить, использовалось ли электронное письмо раньше или нет, прежде чем вставлять данные.
Наконец, нам нужно сделать migrations
перед прыжком в testing
.
migrations/migration.go
migration
прост, вам просто нужно вызвать db.AutoMigrate
вместе со всеми моделями, которые нужно перенести.
.env
будет содержать эту конфигурацию, измененную в соответствии с вашими
DB_HOST=127.0.0.1 DB_PORT=3306 DB_USER=root DB_PASS= DB_DATABASE=go_mysql_suite
Этот код уже работает нормально, но мы создадим тест отсюда.
Suite Test
tests/suite_test.go
suite.Suite
из testify
предоставьте нам 4 interface
, которые мы можем использовать: SetupTest, TearDownTest, SetupSuite, TearDownSuite
.
SetupSuite
будет запущен первым для инициализации необходимых данных Suite.TearDownSuite
запустится последним, после того, как все тесты пройдены.SetupTest
будет запущен перед тестом.TearDownTest
запустится после теста.
Функция TestSuite
запустит тест, и имя функции должно начинаться с Test
(префикс).
Мы инициализируем соединение с базой данных и миграцию в SetupSuite
, а затем закрываем соединение и удаляем все таблицы в TearDownSuite
. Мы устанавливаем нашу тестовую среду, используя os.SetEnv
, а затем os.Unsetenv
, чтобы избежать перезаписи конфигурации в нашем сеансе терминала.
Далее следует, как провести тест с созданным нами suite
.
tests/user_test.go
Префикс каждой тестовой функции ДОЛЖЕН начинаться с Test
, внутри тестов мы можем вызвать нашу службу и создать поток, например, мы создаем пользователя с [email protected]
, а затем с [email protected]
. Конечно, мы ожидаем NoError
, поэтому мы будем использовать testify
подмодуль с именем assert
, который помогает нам с условным assert.NoError, assert.Error
и т. Д.
Когда мы пытаемся вставить третьего пользователя с [email protected]
, мы ожидаем ошибки от этой функции, потому что адрес электронной почты был найден в базе данных.
Попробуем запустить тест.
$ go test ./tests My Output: ok myapp/tests 0.245s // Verbose $ go test -v ./tests My Output (Verbose): === RUN TestSuite --- PASS: TestSuite (0.16s) --- PASS: TestSuite/TestCreateUser (0.02s) PASS ok myapp/tests 0.293s PS D:\go\src\go-mysql-suite> go test ./tests ok myapp/tests 0.245s PS D:\go\src\go-mysql-suite> go test -v ./tests === RUN TestSuite === RUN TestSuite/TestCreateUser --- PASS: TestSuite (0.16s) --- PASS: TestSuite/TestCreateUser (0.02s) PASS ok myapp/tests (cached)
Выводы
Неплохо иметь тест в вашем коде, может быть, вам потребовалось достаточно времени, чтобы написать тест. Но поверьте мне, это поможет вам в дальнейшем, сэкономит ваше время и энергию, которые нужно перепроверять каждый раз перед развертыванием. И что самое приятное, вы можете включить go test
в CI / CD.
На этом все, желаю удачного дня :).