Ускоряем разработку с Quarkus 2.0 при помощи горячей перезагрузки и тестирования

Aug 27, 2021

Quarkus поставляется с набором инструментов, позволяющих разработчикам быстро начать разработку используя расширения для многих популярных IDE. Одной из наиболее известных и простых в использовании функций является возможность выполнять горячую перезагрузку (Live Reload) в реальном времени в режиме разработки (Dev Mode), позволяя разработчику изменять свой код на лету без перезапуска приложения. С выходом новой версии Quarkus 2.0 разработчики полчили ещё больше возможностей.

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

Это перевод статьи Speed up development and save time with Live Reload and Testing in Quarkus 2.0, автор David Dahlin.

Горячая перезагрузка (в режиме разработки)

Quarkus предлагает режим разработки (dev mode), который представляет собой механизм горячего обновления, с помощью которого изменения кода в приложении будут перекомпилированы и перезагружены при обновлении в браузере без необходимости запускать перекомпиляцию вручную. Помимо того, что эта возможность широко используется локально, её также можно использовать в удаленных контейнерах, обеспечивая режим удаленной разработки. Для запуска режима разработки необходимо выполнить следующую команду:

$ ./mvnw quarkus:dev

Результатом будут следующие сообщения в консоли:

$ ./mvnw quarkus:dev
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- quarkus-maven-plugin:2.0.0.Final:dev (default-cli) @ quarkus-crud-reactive-mongodb ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO] Nothing to compile - all classes are up to date
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /src/test/resources
[INFO] Nothing to compile - all classes are up to date
Listening for transport dt_socket at address: 5005
__  ____  __  _____   ___  __ ____  ______ 
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2021-06-28 22:01:06,850 INFO  [org.mon.dri.cluster] (Quarkus Main Thread) Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2021-06-28 22:01:06,870 INFO  [org.mon.dri.cluster] (Quarkus Main Thread) Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2021-06-28 22:01:06,885 INFO  [org.mon.dri.connection] (cluster-rtt-ClusterId{value='60da2a8205cc2d7c5bd0d019', description='null'}-localhost:27017) Opened connection [connectionId{localValue:2, serverValue:11}] to localhost:27017
2021-06-28 22:01:06,885 INFO  [org.mon.dri.connection] (cluster-rtt-ClusterId{value='60da2a8205cc2d7c5bd0d01a', description='null'}-localhost:27017) Opened connection [connectionId{localValue:3, serverValue:13}] to localhost:27017
2021-06-28 22:01:06,885 INFO  [org.mon.dri.connection] (cluster-ClusterId{value='60da2a8205cc2d7c5bd0d019', description='null'}-localhost:27017) Opened connection [connectionId{localValue:1, serverValue:10}] to localhost:27017
2021-06-28 22:01:06,888 INFO  [org.mon.dri.connection] (cluster-ClusterId{value='60da2a8205cc2d7c5bd0d01a', description='null'}-localhost:27017) Opened connection [connectionId{localValue:4, serverValue:12}] to localhost:27017
2021-06-28 22:01:06,888 INFO  [org.mon.dri.cluster] (cluster-ClusterId{value='60da2a8205cc2d7c5bd0d019', description='null'}-localhost:27017) Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=7, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=9103037}
2021-06-28 22:01:06,889 INFO  [org.mon.dri.cluster] (cluster-ClusterId{value='60da2a8205cc2d7c5bd0d01a', description='null'}-localhost:27017) Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=7, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=4754136}
2021-06-28 22:01:06,971 INFO  [io.quarkus] (Quarkus Main Thread) quarkus-crud-reactive-mongodb 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.0.0.Final) started in 1.188s. Listening on: http://localhost:8080
2021-06-28 22:01:06,972 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-06-28 22:01:06,972 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, mongodb-client, mongodb-panache, narayana-jta, resteasy-reactive, smallrye-context-propagation]

--
Tests paused, press [r] to resume, [h] for more options>

В версии Quarkus 2.0, как в примере выше нам предлагается несколько новых опций. При нажатии r запускаются тесты для классов, загруженных в режиме разработки. Результатом запуска будет:

All 1 tests are passing (0 skipped), 1 tests were run in 1547ms. Tests completed at 22:05:53.
Press [r] to re-run, [v] to view full results, [p] to pause, [h] for more options>

Нажав h, разработчику предлагаются следующие варианты: либо перезапустить неудачные тесты, либо запустить отладку последнего сбоя, если такой произошёл. Вот полный список опций:

The following commands are available:
[r] — Re-run all tests
[f] — Re-run failed tests
[b] — Toggle ‘broken only’ mode, where only failing tests are run (disabled)
[v] — Print failures from the last test run
[o] — Toggle test output (disabled)
[p] — Pause tests
[i] — Toggle instrumentation based reload (disabled)
[l] — Toggle live reload (enabled)
[s] — Force live reload scan
[h] — Display this help
[q] — Quit

Если мы создаем приложение, которое работает с базой данных, можно конечно специально сконфигурировать базу данных для тестов. Однако есть более простой способ - Quarkus может предоставить вам доступ к базе данных из коробки, для этого используйте Zero Config Setup (DevServices)!

Zero Config Setup (DevServices)

При тестировании или запуске в режиме разработки Quarkus может предоставить вам базу данных с нулевой конфигурацией из коробки, это называется DevServices. В зависимости от типа базы данных вам может потребоваться установка докера для использования этой функции. DevServices поддерживается для следующих баз данных с открытым исходным кодом:

  • Postgresql (в контейнере)
  • MySQL (в контейнере)
  • MariaDB (в контейнере)
  • H2 (встроенная)
  • Apache Derby (встроенная)
  • DB2 (в контейнере) (требует принятия лицензионного соглашения)
  • MSSQL (в контейнере) (требует принятия лицензионного соглашения)

Если вы хотите использовать DevServices, всё, что вам нужно сделать, это включить соответствующее расширение для типа базы данных, которую вы хотите (либо реактивную, либо JDBC, либо и то, и другое), и не настраивать URL-адрес базы данных, имя пользователя и пароль. Quarkus предоставит базу данных, и вы можете просто начать разработку, не беспокоясь о настройке. Таким образом, у вас может быть запущена локальная база данных, и нет необходимости захламлять общую для всей команды базу. Эта функциональность основана на фреймворке TestContainers, который позволяет разработчику быстро тестировать свое приложение, не уделяя особого внимания настройке базы данных и позволяет сфокусироваться больше на бизнес-логике приложения.

Quarkus CLI

В Quarkus 2.0 изменили и улучшили и утилиту командной строки Quarkus, которая позволяет создавать проекты, управлять расширениями и выполнять важные команды сборки и разработки с помощью более низкоуровневых инструментов сборки проектов. Для установки можно воспользоваться следующей командой:

$ curl -Ls https://sh.jbang.dev | bash -s - app install --fresh --force quarkus@quarkusio

После установки мы можем выполнять следующие команды. Проверить версию:

$ quarkus --version
Client Version {quarkus-version}

Создать новый проект Quarkus:

$ quarkus create
-----------

applying codestarts...
  java
  maven
  quarkus
  config-properties
  dockerfiles
  maven-wrapper
  resteasy-codestart

-----------
[SUCCESS]  quarkus project has been successfully generated in:
--> /<output-dir>/code-with-quarkus

Мы также можем изменять идентификатор артефакта и другую конфигурацию проекта:

$ quarkus create app --group-id com.foo --artifact-id bar --version 1.0
version 1.0
-----------

applying codestarts...
  java
  maven
  quarkus
  config-properties
  dockerfiles
  maven-wrapper
  resteasy-codestart

-----------
[SUCCESS]  quarkus project has been successfully generated in:
--> /<output-dir>/bar
-----------

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

$ quarkus ext ls

Поиск расширений

Используйте параметр –installable или -i для вывода списка расширений, которые можно установить с платформы Quarkus, которую использует проект. Поиск можно сузить или отфильтровать с помощью поиска (–search или -s):

$ quarkus ext list --concise -i -s jdbc
JDBC Driver - DB2                                  quarkus-jdbc-db2
JDBC Driver - PostgreSQL                           quarkus-jdbc-postgresql
JDBC Driver - H2                                   quarkus-jdbc-h2
JDBC Driver - MariaDB                              quarkus-jdbc-mariadb
JDBC Driver - Microsoft SQL Server                 quarkus-jdbc-mssql
JDBC Driver - MySQL                                quarkus-jdbc-mysql
JDBC Driver - Oracle                               quarkus-jdbc-oracle
JDBC Driver - Derby                                quarkus-jdbc-derby
Elytron Security JDBC                              quarkus-elytron-security-jdbc
Agroal - Database connection pool                  quarkus-agroal

Добавление расширений

Утилита командной строки Quarkus может добавить расширения Quarkus в ваш проект с помощью команды «добавить»:

$ quarkus ext add kubernetes health
[SUCCESS]  Extension io.quarkus:quarkus-kubernetes has been installed
[SUCCESS]  Extension io.quarkus:quarkus-smallrye-health has been installed

Удаление расширений

Утилита командной строки Quarkus может удалять расширения из вашего проекта с помощью команды «удалить»:

$ quarkus ext rm kubernetes
[SUCCESS]  Extension io.quarkus:quarkus-kubernetes has been uninstalled

Сборка проекта

Для сборки проекта с помощью Quarkus CLI (в этом примере используется конфигурация по умолчанию) используйте следующую команду:

$ quarkus build

Вход в режим разработки с помощью утилиты командной строки:

$ quarkus dev --help

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

$ quarkus dev

[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< org.acme:code-with-quarkus >---------------------
[INFO] Building code-with-quarkus 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
...
Listening for transport dt_socket at address: 5005
__  ____  __  _____   ___  __ ____  ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2021-05-27 10:15:56,032 INFO  [io.quarkus] (Quarkus Main Thread) code-with-quarkus 1.0.0-SNAPSHOT on JVM (powered by Quarkus 999-SNAPSHOT) started in 1.387s. Listening on: http://localhost:8080
2021-05-27 10:15:56,035 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-05-27 10:15:56,035 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy, smallrye-context-propagation]
--
Tests paused, press [r] to resume

Наличие этих инструментов и функций сборки позволяет разработчикам больше сосредоточиться на непосредственной разработке приложения без какого-либо громоздкого предварительного процесса настройки скелета проекта или базы данных. Если кто-то предпочитает способ начальной конфигурации проекта онлайн в стиле Spring Initializr, всегда можно использовать онлайн конфигуратор Quarkus https://code.quarkus.io/. Там же проект может быть загружен в вашу учетную запись GitHub.