
Quarkusによる開発者の生産性向上: ⑤継続的テストのサポート
はじめに
この記事は、Quarkus in Actionのサンプルアプリケーションを使ってQuarkusの機能を紹介するシリーズの9回目です。今回は継続的テストを紹介します。
本記事に登場するQuarkus CLIのインストール方法や実行環境については以下の記事をご覧ください。
継続的テスト
これまでの記事で、開発者の生産性を向上するQuarkusの機能について見てきました。
Dev Modeでは、手動でビルドを起動しなくとも、コードが変更されることでQuarkusにアプリケーションがリロードされ、アプリケーションの動作を確認することができました。Dev UIを使うと、アプリケーションの設定やエクステンションの設定が簡単にできました。Dev Servicesは、テストで必要なサービスを自動で起動してくれました。
さらに、Dev Modeにおいて継続的テストの設定が有効になっていると、開発の作業をしている間に、テストを並行して実行することができます。テストの実行は開発作業中のアプリケーションに影響を与えません。テストは別のクラスローダーを使い隔離された別のアプリケーションで実行されるので、開発者はテストの終了を待たずにアプリケーションにアクセス可能です。
この継続的テストの設定により、コードの変更によってアプリケーションがリロードされると、テストが自動的に実行されます。テスト結果は、Dev ModeのターミナルログやDev UI上で表示されます。こうした複数のツールによる連携によって、開発ワークフローの中で継続的なテストを効率的に実行できます。
対象アプリケーションの準備 (v3.15.1使用)
継続的テストを説明するため、restエクステンションを含むquarkus-in-actionアプリケーションを準備します。Quarkusのバージョンは、Quarkus in Actionでサンプルプログラムで指定されている 3.15.1 を指定します。quarkus create appコマンドを実行するときに、-Pオプションでバージョンが指定可能です。
$ quarkus create app org.acme:quarkus-in-action --extension quarkus-rest -P 3.15.1
-----------
selected extensions:
- io.quarkus:quarkus-rest
<略>
-----------
[SUCCESS] ✅ quarkus project has been successfully generated in:
--> /home/minamoto/Work/quarkus/quarkus-in-action
-----------
Navigate into this directory and get started: quarkus dev
注意
前回の記事までQuarkusの最新版を使うようにしていたのですが、継続的テストの動作確認中にQuarkus in Actionと挙動が異なるところがあったので、今回から本で指定しているQuarkusのバージョン3.15.1に合わせることにしました。
quarkus create appコマンドで作成したプロジェクトのディレクトリに移動し、quarkus devコマンドを使ってDevモードでアプリケーションを実行しておいてください。
$ cd quarkus-in-action
$ quarkus dev
[INFO] Scanning for projects...
<略>
Listening for transport dt_socket at address: 5005
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2025-02-24 19:17:36,987 INFO [io.quarkus] (Quarkus Main Thread) quarkus-in-action 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.15.1) started in 1.118s. Listening on: http://localhost:8080
2025-02-24 19:17:36,988 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2025-02-24 19:17:36,989 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, rest, smallrye-context-propagation, vertx]
--
Tests paused
Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
Quarkus in Action プロジェクトにおけるテスト
テストコードの確認
quarkus-in-actionのテストコードの内容を確認します。src/test/java/org/acme/GreetingResourceTest.javaをIDEを使って開いてみてください。QuarkusのテスティングフレームワークはJUnitと統合されています。テストコードのクラスには@QuarkusTestというアノテーションをつけ、各テストメソッドには@Testをつけます。

このGreetingResourceTestクラスのtestHelloEndpoint() メソッドは、RestAssueredという (Quarkusとは別の) テスティングフレームワークを使っています。 これはREST APIの呼び出しテストをするときによく使われるもので、テストコードは、Given-When-Thenの3つの部分から構成されます。
Given: (URLやパラメーターやヘッダーなど) リクエストの準備をする。
When: GET/POST/DELETEなどのRESTアクションを指定する。
Then: レスポンスを解析しテスト結果を判別するロジックを書く。
@Test
void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200)
.body(is("Hello from Quarkus REST"));
}
上のテストは、/helloというパスにHTTP GETのリクエストを送信したときに、テスト結果はHTTPステータスが200で、ボディは"Hello from Quarkus REST"になるべき、という意味になります。
このようにREST APIのリクエスト送信の際に低レベルなネットワークライブラリを使用することなく、.get("/hello")だけでよいのでテストコードをすっきりと記述することができます。
TIP
RestAssuredを使うとRESTの統合テストで比較的簡単に記述できるようになります。テストのためにリクエストにパラメーターを設定したり、レスポンスに含まれるJSONデータを解析するのも容易です。詳細はドキュメントをご覧ください。
テストの手動実行
Dev Modeでテストを開始するにはターミナル上で [r] を押します。テストが成功すると以下のようなメッセージが出力されます。

ここで意図的にテストを失敗させてみます。
src/main/java/org/acme/GreetingResource.javaのhello()から返される文字列を"Hello from Quarkus REST"から"Hello note"に置き換えて、ファイルを保存します。テストコードで期待している文字列と異なりますからテストはエラーになるはずです。
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello note";
}
}
上記のファイルを保存すると、テストが自動で実行され、エラーが報告されます。

テストの自動実行
application.propertiesにおいて quarkus.test.continuous-testing プロパティをENABLEDにすると、継続的テストが有効に設定されます。デフォルトではDISABLEDに設定されています。
先ほど [r] を押してテストを手動で開始したのは、このプロパティがDISABLEDだったからです。Dev Mode開始直後からテストを自動で開始するように設定を変更してみましょう。
Devモードのターミナルで [d] を押してDev UIを起動し、quarkus.test.continuous-testingの値を設定するためメニューからENABLED選択してください。Dev UI上でのプロパティの変更はすぐにapplication.propertiesに反映されます。

継続的テストの設定が有効になったので、[r] を押さなくともテストが自動実行されるはずです。これを確認するため、ターミナルで [q] コマンドを押して一旦Dev Modeを終了させ、quarkus devコマンドを実行して再度Dev Modeを開始してください。
起動直後に自動的にテストが実行されターミナルにエラーが表示されます。次に、src/main/java/org/acme/GreetingResource.javaのhello()で返される文字列を"Hello from Quarkus REST"に戻してファイルを保存してください。ターミナル上でテストが成功したというメッセージを確認できるはずです。

テスト出力の制御
Devモードのターミナルで [o] を押すと、テストの出力を制御することができます。デフォルトはテスト出力がDISABLEDになっています。[o] を叩くたびに、DISABLE→ENABLED→DISABLEのように切り替わります。
2025-02-23 23:43:10,113 INFO [io.qua.test] (Aesh InputStream Reader) Test output enabled
2025-02-23 23:43:13,736 INFO [io.qua.test] (Aesh InputStream Reader) Test output disabled
2025-02-23 23:43:16,980 INFO [io.qua.test] (Aesh InputStream Reader) Test output enabled
2025-02-23 23:43:20,689 INFO [io.qua.test] (Aesh InputStream Reader) Test output disabled
2025-02-23 23:43:24,186 INFO [io.qua.test] (Aesh InputStream Reader) Test output enabled
[o] を押してENABLEDの状態にします。次に [r] を押すとテストを再実行され、次のようにテストを開始したところからログが出力されます。
2025-02-23 23:43:24,186 INFO [io.qua.test] (Aesh InputStream Reader) Test output enabled
2025-02-23 23:46:15,917 INFO [io.qua.test] (Test runner thread) Running 1/1. Running: #JUnit Jupiter
2025-02-23 23:46:15,919 INFO [io.qua.test] (Test runner thread) Running 1/1. Running: org.acme.GreetingResourceTest#GreetingResourceTest
2025-02-23 23:46:16,088 INFO [io.quarkus] (Test runner thread) quarkus-in-action 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.18.4) started in 0.168s. Listening on: http://localhost:8081
2025-02-23 23:46:16,089 INFO [io.quarkus] (Test runner thread) Profile test activated.
2025-02-23 23:46:16,090 INFO [io.quarkus] (Test runner thread) Installed features: [cdi, rest, smallrye-context-propagation, vertx]
2025-02-23 23:46:16,092 INFO [io.qua.test] (Test runner thread) Running 1/1. Running: org.acme.GreetingResourceTest#testHelloEndpoint()
2025-02-23 23:46:16,106 INFO [io.quarkus] (Test runner thread) quarkus-in-action(test application) stopped in 0.004s
--
All 1 test is passing (0 skipped), 1 test was run in 202ms. Tests completed at 23:46:16.
Press [e] to edit command line args (currently ''), [r] to re-run, [o] Toggle test output, [:] for the terminal, [h] for more options>
[o] を押してDISABLEDの状態します。次に [r] を押すと、テストの結果のみが表示されます。
2025-02-23 23:48:13,308 INFO [io.qua.test] (Aesh InputStream Reader) Test output disabled
--
All 1 test is passing (0 skipped), 1 test was run in 193ms. Tests completed at 23:48:16.
Press [e] to edit command line args (currently ''), [r] to re-run, [o] Toggle test output, [:] for the terminal, [h] for more options>
Dev UIによるテスト結果の出力
Dev UI上でテストを開始したり、テスト結果を確認することもできます。[d] を押してDev UIを起動し、左側のメニューからContinuous Testingを選択してください。
quarkus.test.continuous-testing プロパティをDISABLEDにしている場合はStartボタンを押してテストを起動することができます。

quarkus.test.continuous-testing プロパティをENABLEDにしている場合やすでに手動でテストを開始している場合は、テスト結果が表示されます。
テストが成功した場合には緑のバーが表示されます。

テストが失敗した場合には赤のバーが表示され、テストクラスをクリックするとテストに失敗したメッセージが表示されます。

TIP
この記事で説明している継続的テストではMavenでテストを実施したときに得られるテストレポートは作成されません。プロジェクトのディレクトリでmvn testを実行してください。
まとめ
この記事ではDev Modeにおける継続的テストを説明しました。
Dev Modeのターミナルからテストを起動する方法
継続的テストの自動実行のためのプロパティ設定
Dev UIからテストを起動する方法
Dev UI上でのテスト結果の確認
継続的テストのためのターミナルのコマンドや設定プロパティの詳細については以下を参照してください。