Почему очень важно тестировать ваше приложение в целом, а не пропускать часть БД.
Зачем тестировать также часть БД?
При разработке приложения на долгосрочную перспективу абсолютно необходимо покрыть как можно больше — и разумно — тестами, чтобы убедиться, что любые модификации кода не изменят желаемое поведение или не приведут к критическим ошибкам.
В большинстве серверных приложений база данных является одной из наиболее важных частей, поэтому пропуск или насмешка над всей ее логикой — это просто бомба, ожидающая своего срабатывания. Просто представьте, что ваши серверы получают сотни запросов в секунду, и внезапно ВСЕ из них выходят из строя или вызывают побочные эффекты, потому что вы не протестировали должным образом код, взаимодействующий с базой данных… 💣💥🤯
Кроме того, взаимодействие с базой данных и ее определенная логика являются частью вашего приложения, поэтому оно также заслуживает того, чтобы его обрабатывали и тестировали, как и все остальное 😉
Почему In-Memory DB? Разве мы не можем просто использовать «нормальный»?
Теперь, когда мы согласились с тем, что нам также необходимо автоматизировать тестирование взаимодействия с нашей базой данных — если нет, пожалуйста, остановитесь здесь и прочитайте последний абзац еще раз — давайте перейдем к КАК.
Если бы мы подошли к этому очень прямолинейно, мы бы загрузили MongoDB как двоичный файл и установили его или запустили образ MongoDB Docker, чтобы иметь запущенный локальный экземпляр нашей MongoDB, с которым мы могли бы взаимодействовать. И хотя он определенно рекомендуется (в данном случае я бы предпочел Docker) для РУЧНОГО тестирования на вашем локальном компьютере, это не лучший способ для автоматического тестирования.
Есть несколько проблем с этим подходом:
- Это определенно не сработает для конвейеров CI/CD, по крайней мере, без МНОГО дополнительных затрат времени и ресурсов, таких как запуск чистого контейнера докера для каждого тестового примера. Стоит много ресурсов и вводит много дополнительной сложности.
- При локальном запуске тестов вам всегда придется полностью очищать локальную БД, чтобы создать чистое состояние для ваших тестов, что приведет к потере данных, которые вы могли бы в настоящее время использовать для ручного тестирования.
- Не очень эффективно всегда писать в реальную существующую БД и полностью очищать ее после каждого теста. В памяти просто быстрее
Таким образом, должно быть совершенно ясно, что подход в памяти должен быть предпочтительным.
Фактический код
После того, как мы также договорились об использовании подхода в памяти для тестирования нашего приложения вместе с базой данных, мы можем перейти к фактическому коду и тому, как его настроить.
Как и во всех моих уроках, я подготовил для вас небольшой репозиторий на GitHub. Вы можете просто клонировать его и сразу приступить к работе над своим новым проектом или просто использовать его как ссылку на эту статью. Обратите внимание, что в этой статье я упомяну только самые важные файлы, а не все файлы репозитория.
Настройка тестовой конфигурации
Для использования MongoDB в памяти в ваших тестах вам необходимо установить две зависимости dev, я предполагаю, что вы уже установили Jest и клиент MongoDB.
npm i --save-dev
mongodb-memory-server @shelf/jest-mongodb
После этого нам нужно создать несколько файлов для настройки Jest, чтобы он использовал MongoDB в памяти и запускал ее перед запуском тестовых случаев.
Чтобы упростить понимание, я добавил комментарии прямо в код, а не в эту статью, чтобы вы могли видеть объяснение напрямую, не переходя между статьей и кодом.
Настройте фактические тесты
После настройки наших тестовых конфигураций мы должны определить наши тесты.
Если вы проверите вышеуказанный репозиторий, вы увидите, что у нас есть dbhelper.ts
и соответствующий тестовый файлdbhelper.spec.ts
. Мы не используем какой-либо причудливый HTTP-сервер в этом примере/проекте, поскольку он просто не нужен, даже если он может быть наиболее распространенным вариантом использования при использовании некоторой БД.
Фактическая реализация dbhelper.ts
не важна, просто ожидайте, что она предоставляет класс с именем DBHelper
с общедоступными методами для
- Запуск —
createConnection(mongoHost, mongoDbName)
- Выключение —
closeConnection()
- Добавление людей —
addPersonsToDb(persons)
- Получение всех лиц —
getPersonsFromDb()
Но, конечно, вы можете проверить фактическую реализацию в репозитории.
Поэтому, прежде чем мы начнем выполнять тесты, мы должны напомнить себе, что наш файл jest.setup.ts
заботится о предоставлении переменных среды для установления соединения с MongoDB — обычно это делается с помощью обычных переменных среды при запуске приложения — и гарантирует, что MongoDB находится в чистом состоянии. перед каждым тестовым запуском. Также обратите внимание, что следующие тестовые примеры являются просто примерами и не охватывают все возможные тестовые примеры, которые вы должны написать в реальной реализации.
Если мы теперь используем npm run test
для запуска выше dbhelper.spec.ts
, мы увидим, что все тестовые случаи проходят за короткий промежуток времени.
Исправление проблем
Если Jest сообщает вам, что он не завершился после завершения тестовых прогонов, проблема, скорее всего, в том, что у вас все еще есть открытое соединение с вашей базой данных.
Так что перепроверьте, правильно ли вы закрыли соединения в блоках jest.setup.ts
и dbhelper.spec.ts
в блоках afterAll
и нет ли утечек.
Вывод
Я надеюсь, что смог показать вам, что не так сложно настроить некоторую MongoDB в памяти для ваших автоматических тестов и какие преимущества они имеют по сравнению с использованием реальной базы данных.
Самое сложное здесь, собственно, конфигурация и правильная настройка, но кроме этого, собственно тестирование простое и ничем не отличается от того, к чему вы должны привыкнуть.
Спасибо, что нашли время прочитать мою статью.
Если у вас есть какие-либо вопросы или дополнения, не стесняйтесь использовать раздел комментариев или написать мне в LinkedIn или Twitter, чтобы связаться со мной 😊