Статьи

Тесты Quarkus с использованием Testcontainers и PostgreSQL

Testcontainers — это библиотека Java, которая позволяет легко интегрировать контейнеры Docker в тесты JUnit. В контейнеризованном мире нет смысла усложнять настройку тестов встроенными базами данных и сервисами. Вместо этого используйте запуск ваших сервисов в Docker и позвольте Testcontainers управлять этим за вас. Так что если вам нужны Redis, MongoDB или PostgreSQL в ваших тестах — Testcontainers могут стать вашим хорошим другом.

В этом блоге вы узнаете, как настроить Testcontainers для управления экземпляром PostgreSQL в интеграционных тестах Quarkus.

зависимости

Чтобы использовать Testcontainers с PostgreSQL, вам нужно добавить следующие зависимости в pom.xml :

01
02
03
04
05
06
07
08
09
10
11
12
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers</artifactId>
    <version>1.12.5</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>
    <version>1.12.5</version>
    <scope>test</scope>
</dependency>

Примечание: Testcontainers предоставляет плагин JUnit 5, но в сценарии, представленном в этой статье, он не нужен.

Тестирование конфигурации источника данных

Конфигурация PostgreSQL по умолчанию в приложении Quarkus может выглядеть следующим образом:

1
2
3
4
quarkus.datasource.url=jdbc:postgresql://localhost:5432/some-db
quarkus.datasource.driver=org.postgresql.Driver
quarkus.datasource.username=user
quarkus.datasource.password=password

По умолчанию эта конфигурация будет использоваться в любом активном профиле. Встроенные профили в Quarkus: dev , prod и test . test профиль будет использоваться каждый раз при запуске @QuarkusTest .

Вы можете настроить профиль test , указав %test. префикс к свойствам конфигурации в файле src/main/application.properties . Это позволяет настроить (и запустить) контейнер базы данных PostgreSQL через схему URL JDBC . Для этого обязательно:

  • установите для драйвера значение org.testcontainers.jdbc.ContainerDatabaseDriver . Этот специальный драйвер гарантирует, что контейнер Docker будет создан и запущен, как только нам понадобится источник данных в приложении,
  • установите диалект явно в org.hibernate.dialect.PostgreSQL9Dialect иначе вы получите исключение при запуске приложения:
1
org.junit.jupiter.api.extension.TestInstantiationException: TestInstanceFactory [io.quarkus.test.junit.QuarkusTestExtension] failed to instantiate test class [pl.codeleak.samples.OwnerResourceTest]: io.quarkus.builder.BuildException: Build failure: Build failed due to errors

[ошибка]

: Шаг компоновки Добавьте явное свойство ‘quarkus.hibernate-orm.dialect’. в io.quarkus.hibernate.orm.deployment.HibernateOrmProcessor.guessDialect (HibernateOrmProcessor.java:715)

  • установите для URL JDBC значение jdbc:tc:postgresql:latest:///dbname чтобы Testcontainers знал, какую версию PostgreSQL использовать при запуске контейнера.

Полная конфигурация:

1
2
3
4
5
6
7
8
# initializes container for driver initialization
%test.quarkus.datasource.driver=org.testcontainers.jdbc.ContainerDatabaseDriver
 
# dialect must be set explicitly
%test.quarkus.hibernate-orm.dialect=org.hibernate.dialect.PostgreSQL9Dialect
 
# Testcontainers JDBC URL
%test.quarkus.datasource.url=jdbc:tc:postgresql:latest:///dbname

Имея конфигурацию, вы можете запустить тесты и наблюдать, что тестовый контейнер создан для теста:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
$ ./mvnw clean test
 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running pl.codeleak.samples.OwnerResourceTest
2020-02-27 21:09:21,096 INFO  [io.qua.fly.FlywayProcessor] (build-8) Adding application migrations in path '/Users/rafal.borowiec/Projects/quarkus/quarkus-postgres-sample/target/classes/db/migration' using protocol 'file'
2020-02-27 21:09:23,084 INFO  [org.fly.cor.int.lic.VersionPrinter] (main) Flyway Community Edition 6.1.4 by Redgate
2020-02-27 21:09:23,176 INFO  [org.tes.doc.DockerClientProviderStrategy] (Agroal_1012722761) Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2020-02-27 21:09:23,658 INFO  [org.tes.doc.UnixSocketClientProviderStrategy] (Agroal_1012722761) Accessing docker with local Unix socket
2020-02-27 21:09:23,659 INFO  [org.tes.doc.DockerClientProviderStrategy] (Agroal_1012722761) Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2020-02-27 21:09:23,780 INFO  [org.tes.DockerClientFactory] (Agroal_1012722761) Docker host IP address is localhost
2020-02-27 21:09:23,815 INFO  [org.tes.DockerClientFactory] (Agroal_1012722761) Connected to docker:
  Server Version: 19.03.2
  API Version: 1.40
  Operating System: Docker Desktop
  Total Memory: 1998 MB
2020-02-27 21:09:23,957 INFO  [org.tes.uti.RegistryAuthLocator] (Agroal_1012722761) Credential helper/store (docker-credential-desktop) does not have credentials for quay.io
2020-02-27 21:09:24,857 INFO  [org.tes.DockerClientFactory] (Agroal_1012722761) Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
2020-02-27 21:09:24,857 INFO  [org.tes.DockerClientFactory] (Agroal_1012722761) Checking the system...
2020-02-27 21:09:24,858 INFO  [org.tes.DockerClientFactory] (Agroal_1012722761) ✔︎ Docker server version should be at least 1.6.0
2020-02-27 21:09:25,040 INFO  [org.tes.DockerClientFactory] (Agroal_1012722761) ✔︎ Docker environment should have more than 2GB free disk space
2020-02-27 21:09:25,078 INFO  [? [postgres:latest]] (Agroal_1012722761) Creating container for image: postgres:latest
2020-02-27 21:09:25,135 INFO  [org.tes.uti.RegistryAuthLocator] (Agroal_1012722761) Credential helper/store (docker-credential-desktop) does not have credentials for index.docker.io
2020-02-27 21:09:25,247 INFO  [? [postgres:latest]] (Agroal_1012722761) Starting container with ID: b436fdabccbe51ba3e6d778d4429505473995d4185a200aef35c4c30b2159369
2020-02-27 21:09:25,779 INFO  [? [postgres:latest]] (Agroal_1012722761) Container postgres:latest is starting: b436fdabccbe51ba3e6d778d4429505473995d4185a200aef35c4c30b2159369
2020-02-27 21:09:26,896 INFO  [? [postgres:latest]] (Agroal_1012722761) Container postgres:latest started in PT3.731519S
2020-02-27 21:09:27,107 INFO  [org.fly.cor.int.dat.DatabaseFactory] (main) Database: jdbc:postgresql://localhost:32830/test (PostgreSQL 12.2)
2020-02-27 21:09:27,146 INFO  [org.fly.cor.int.sch.JdbcTableSchemaHistory] (main) Creating Schema History table "public"."flyway_schema_history" ...
2020-02-27 21:09:27,188 INFO  [org.fly.cor.int.com.DbMigrate] (main) Current version of schema "public": << Empty Schema >>
2020-02-27 21:09:27,193 INFO  [org.fly.cor.int.com.DbMigrate] (main) Migrating schema "public" to version 1.0.0 - Init
2020-02-27 21:09:27,201 INFO  [org.fly.cor.int.sql.DefaultSqlScriptExecutor] (main) DB: table "owners" does not exist, skipping
2020-02-27 21:09:27,226 INFO  [org.fly.cor.int.com.DbMigrate] (main) Successfully applied 1 migration to schema "public" (execution time 00:00.050s)
2020-02-27 21:09:27,726 INFO  [io.quarkus] (main) Quarkus 1.2.1.Final started in 5.761s. Listening on: http://0.0.0.0:8081
2020-02-27 21:09:27,727 INFO  [io.quarkus] (main) Profile test activated.
2020-02-27 21:09:27,727 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, flyway, hibernate-orm, hibernate-orm-panache, hibernate-validator, jdbc-postgresql, narayana-jta, resteasy, resteasy-jackson]
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.091 s - in pl.codeleak.samples.OwnerResourceTest
2020-02-27 21:09:29,975 INFO  [io.quarkus] (main) Quarkus stopped in 0.689s
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  15.375 s
[INFO] Finished at: 2020-02-27T21:09:30+01:00
[INFO] ------------------------------------------------------------------------

Более подробную информацию о конфигурации базы данных можно найти в официальной документации здесь: https://www.testcontainers.org/modules/databases/.

Инициализация тестовой базы данных

У вас есть несколько вариантов инициализации базы данных. Вы можете инициализировать базу данных с помощью Flyway, но вы также можете использовать Testcontainers для запуска сценария инициализации после запуска базы данных, но до возврата соединения в код.

Использование Flyway для инициализации тестовой базы данных

С помощью Flyway сценарии миграции можно настроить только для профиля теста, так же, как мы настроили источник данных — добавив %test. префикс к свойствам конфигурации. Таким образом, вы можете настроить различные местоположения файлов миграции и / или вы можете настроить другой префикс для файлов миграции:

1
2
%test.quarkus.flyway.locations=test_db/migration
%test.quarkus.flyway.sql-migration-prefix=test_

В приведенной выше конфигурации вам может потребоваться создать test/src/resources/test_db/migration и поместить его, например, в файл test_1.0.0_schema.sql (шаблон имени test_version_description.sql ).

Совет: не забудьте добавить расширение pom.xml в pom.xml .

Использование Testcontainers для инициализации тестовой базы данных

Если вы не хотите использовать Flyway в тестах, вы можете инициализировать базу данных с помощью скрипта, загруженного Testcontainers. Файл может быть загружен либо непосредственно из пути к классам, либо из любого места. Единственное, что нужно сделать, это изменить URL JDBC:

1
%test.quarkus.datasource.url=jdbc:tc:postgresql:latest:///dbname?TC_INITSCRIPT=file:src/main/resources/init_pg.sql

или же

1
%test.quarkus.datasource.url=jdbc:tc:postgresql:latest:///dbname?TC_INITSCRIPT=classpath:init_pg.sql

Исходный код

Исходный код этой статьи можно найти на Github: https://github.com/kolorobot/quarkus-postgres-sample (ветвь testcontainers )

связи

Смотреть оригинальную статью здесь: Quarkus тесты с Testcontainers и PostgreSQL

Мнения, высказанные участниками Java Code Geeks, являются их собственными.