Как подготовиться к интеграционным тестам, которые используют PostgreSQL для замены памяти?

Я узнал, что использование реальной базы данных в интеграционных тестах значительно замедляет их. Поэтому я должен использовать базу данных в памяти, которая может значительно увеличить скорость моих интеграционных тестов.

Я использую Springboot для разработки приложений. Как мне настроить PostgreSQL для тестирования? Есть ли в памяти база данных, которая очень совместима с синтаксисом PostgreSQL?

Если нет, как я должен выполнять интеграционные тесты.

3 ответа

Решение

Некоторые из моих тестов БД на реальных postgres занимают 10 мс каждый. и я делаю несколько коммитов в каждом тесте. так:

Чтобы охватить нативные функции postgres, вам нужен один и тот же БД (как вы заметили, h2 и другие БД в памяти не очень совместимы). Postgres не имеет режима в памяти. Для функциональных тестов реальная база данных сама по себе не намного медленнее, чем любые базы данных в памяти. Разница обычно заключается во времени запуска (для Postgres 9.6 это ~4 с). Но если ваш жизненный цикл тестирования является разумным, и вы можете уменьшить количество дБ, начинающихся с 1 или 0 (имея готовую разработку db всегда), тогда проблема перестает быть заметной.

так что получите настоящий postgres и правильно настройте его жизненный цикл. Есть несколько инструментов, которые могут помочь вам решить некоторые из проблем:

  1. https://www.testcontainers.org/ поможет вам обеспечить реальную базу данных.

  2. dbunit - поможет вам очистить данные между тестами

    минусы:

    • требуется много работы для создания и поддержки схемы и данных. особенно когда ваш проект находится в стадии интенсивного развития.
    • это еще один уровень абстракции, так что если вдруг вы захотите использовать некоторую функцию БД, которая не поддерживается этим инструментом, может быть сложно протестировать ее
  3. testegration - намеревается предоставить вам полный, готовый к использованию и расширяемый жизненный цикл (раскрытие: я создатель).

    минусы:

    • бесплатно только для небольших проектов
    • очень молодой проект

другим шагом было бы перенести базу данных в память на уровне ОС. опять же, время первого запуска будет похоже, так как все должно быть загружено. некоторые отправные точки здесь и здесь

минусы:

  • каждый разработчик в вашей команде должен изменить свою местную среду
  • не переносим между операционными системами (если ваша команда имеет гетерогенные среды)

Вы действительно можете получить настоящий Postgres, который будет тихо работать в тестовой среде.

Я также предлагаю вам использовать докеризованную базу данных, но использовать tmpfs для сопоставления памяти папки данных:

docker run --name postgres95 -p 5432:5432 --tmpfs /var/lib/postgresql/data:rw -e POSTGRES_PASSWORD=admin -d postgres:9.5.6

Это настолько близко к "в памяти", которое вы можете получить, используя настоящую вещь.

Я считаю, что одна из основных проблем с медленными интеграционными тестами - это не производительность самой базы данных, а время, необходимое для ее настройки для каждого теста.

Я написал небольшую библиотеку, которая поможет вам быстро восстановить базу данных до "чистого" состояния. Таким образом, вам нужно только один раз запустить дорогостоящую миграцию базы данных, а затем вы сможете быстро восстановить базу данных для каждого теста.

Мы использовали его в производительной системе, чтобы получить 4-кратное ускорение в наших интеграционных тестах:

https://github.com/ayedo/postgres-db-restore

Этот вопрос требует мнений, но здесь идет:

Если вы хотите протестировать приложение, которое будет использовать PostgreSQL, вам придется использовать PostgreSQL для своих тестов. Диалекты и поведение SQL просто сильно различаются в разных системах управления базами данных.

Вы можете сделать PostgreSQL довольно быстрым, если вы используете базу данных, которая достаточно мала, чтобы поместиться в ОЗУ, что должно быть возможно для интеграционных тестов, которые нацелены только на функциональность, а не на общую производительность.

Как вы получаете доступ к базе данных в вашем приложении? Использование простого JDBC или использование абстракции поверх него (JPA)?

Если вы используете слой абстракции и, например, JPQL, диалект не так важен, и, возможно, вы можете использовать базу данных H2 в памяти для своих тестов.

Если вам нужно использовать нативные операторы PostgreSQL, другим способом было бы использовать докеризированную базу данных с использованием Testcontainers. Это не ускорит тестирование, но облегчит настройку и очистку среды.

Другие вопросы по тегам