本連載の第1回で、マイクロサービスの一般的な特徴やメリットについて紹介しました。その際、マイクロサービスでは開発体制やアプリケーション構成、リリース単位などについて、「これまでとは異なるかたちで行うことを要求される」とご説明したかと思います。
実際のプロジェクトでマイクロサービスアーキテクチャを採用する場合、アプリケーションを迅速にリリースし、顧客やエンドユーザーの要求/フィードバックに応じて機能追加や仕様変更を行っていくケースが多いでしょう。
機能追加などでアプリケーションを改修する場合、追加した部分のテストはもちろん、リファクタリングのほか、変更が入っていない既存部分も無影響確認テストなどを繰り返し実施する必要があります。そのため、試験においてはテストコードを実装し、ソースコードコミットやビルド時にテストを実行するなどして、改修時の問題の早期検出の仕組みを整えること、また、継続的インテグレーションによって極力自動化し、修正にかかる工数を省力化しておくことが重要になります。
とはいえ、テストコードの実装には相応の工数が必要です(筆者の感覚値ですが、アプリケーションコードの実装に比べてテストコードの実装はその3倍近い工数がかかる場合もあります)。
初めから完璧にテストコードを整備しておく必要もありませんし、必要以上のテストコードの実装でかえって開発のアジリティを損なうようでは本末転倒です。ただ、テストがおろそかになるとせっかくの継続的インテグレーションも機能しません。
開発のスピードと品質を両立するには、テスト計画やスコープ、検証の観点を明示的に定めておくことが重要です。以降では、どのようなテスト戦略の下で、どんなテストを実施すべきか、SpringBootを使ったアプリケーションテスト実装を通して実践していきます。
アプリケーションのパッケージ/コンポーネント構成
テスト戦略の話に入る前に、本連載で構築するマイクロサービスアーキテクチャでのアプリケーションのパッケージ/コンポーネント構成について説明します。アプリケーションでは、以下のようにBackendとBackendForFrontend(BFF)に分けてコンテナを構築しています。
本連載では、Backendでデプロイしているアプリケーションがマイクロサービスに相当します。そして、各マイクロサービスを呼び出し、呼び出した結果をフロントエンド(クライアント)向けに画面(HTML)などにアグリゲーション(集約)して返却するのが、BFFの役割です。
また、Backend、BFFともにアプリケーションのコンポーネントはそれぞれ、アプリケーションレイヤ、ドメインレイヤ、インフラストラクチャレイヤで分割して構成するものとします。
以降登場する各レイヤやコンポーネントの用語の意味や役割はTERASOLUNAのガイドライン「アプリケーションのレイヤ化」での記述にほぼ準拠するので、必要に応じて、TERASOLUNAのサイトを参照してください。
なお、実際に作成したアプリケーションはGitHub上にコミットしています。以降、解説で使用しているソースコードでは、記述を一部省略しているので、実行コードを作成する場合は、必要に応じて適宜GitHub上のソースコードも参照してください。
まず、マイクロサービスとなるBackendアプリケーションのパッケージ/コンポーネント構成は以下の通りです。
なお、アプリケーション内のデータベースアクセスはSpring Data JPAを用いており、ここでは詳細な解説は行いませんが、詳細は TERASOLUNAのガイドライン「データベースアクセス(JPA編)」 を適宜参照してください。また、テストではインメモリDBであるHSQLを利用します。
また、マイクロサービスを呼び出すBFFアプリケーション(Webアプリケーションとなります)のパッケージ/コンポーネント構成は以下の通りです。
WebアプリケーションのHTMLテンプレートエンジンとしてThymeleafを使用しています。こちらも詳細な説明は割愛しますが、必要に応じて、Thymeleafの公式ドキュメントやMacchinetta Frameworkテンプレートエンジンを参照してください。
また、2つのアプリケーションで共通して使用する部品のパッケージ/コンポーネント構成は以下の通りです。
主な構成要素は、マイクロサービスから返却されるResourceクラスと、アプリケーション基盤部品ですが、ほとんどがマイクロサービスと連携する場合やテストコードの検証に必要になったために実装した共通部品です。
なお、例外の種類や考え方、SpringFrameworkを用いた例外ハンドリングの基本はTERASOLUNAガイドラインの例外ハンドリングのページや、RESTful Web Serviceの例外ハンドリングのページも参考にしてください。
次節以降のテストコード実装の解説時に、上記のいくつかのコンポーネントについては必要に応じて説明しますが、ここで示しておきたいのは、Backend/BFFともに「Controller」「Service」「Repository」がアプリケーションの中核的なコンポーネントだということです。SpringBootをベースとするアプリケーションでは、提供されているアノテーションの関係上、同じようなコンポーネント構成をとるケースがほとんどなので、以降は、Controller、Service、Repositoryに関するテストを前提として話を進めていきます。
アプリケーションのテスト観点
先述したマイクロサービス(Backend)とWebアプリケーション(BFF)のコンポーネント構成では、以下のような観点で各テストごとに品質を担保していくのがベターです。
アプリケーション | 試験 | コンポーネント | 検証観点 |
---|---|---|---|
マイクロサービス (Backend) |
単体試験 | Respository | ・エンティティクラスがテーブル定義と一致しているか ・O/Rマッピング設定が妥当か ・記載したSQLクエリや集合関数が正しく実行されるか ・該当しないデータが発生した場合に期待された戻り値が返されるか ・命名規約によるSQLクエリの自動組立 が正しく実行されるか ・指定した結合条件でデータが正しく取得できるか |
Service | ・Service実行の結果、正しくアウトプットが返されるか ・Service実行の結果、正しくビジネス例外が返されるか ・例外に正しくメッセージが設定されているか |
||
Controller | ・指定したHTTPメソッドやURLで正しくリクエストハンドリングされるか ・リクエストパラメータやパス変数が正しくマッピングされるか ・入力チェックが正しく行われているか ・入力チェックエラーやビジネスエラー発生時に正しいHTTPステータスを返却するか ・入力チェックエラーやビジネスエラー発生時に正しいメッセージやパラメータを返却するか ・レイヤ間のモデルオブジェクト変換は正しくマッピングされるか |
||
結合試験 | Service⇔Repository | ・データベースから正しく値が取得できるか ・データベースへ正しくデータが反映できるか ・設定ファイルが正しく動作するか |
|
Controller⇔Service⇔Repository | ・期待したレスポンスが返却されるか ・モデル間のデータマッピングが正しく実行されているか ・設定ファイルが正しく動作するか |
||
Webアプリケーション (BFF) |
単体試験 | Respository(RestClient) | ・正しくビジネス例外が返されるか ・異常なレスポンスを受け取った場合正しくシステム例外が返されるか ・例外に正しくメッセージが設定されるか ・マイクロサービス側のサーバエラー発生時に正しくシステム例外が返されるか |
Service | ・Service実行の結果、正しくアウトプットが返されるか ・Service実行の結果、正しくビジネス例外が返されるか ・例外に正しくメッセージが設定されているか |
||
(View⇔)Controller | ・指定したHTTPメソッドやURLで正しくリクエストハンドリングされるか ・リクエストパラメータやパス変数が正しくマッピングされるか ・入力チェックが正しく行われているか ・入力チェックやビジネスエラー発生時に正しいメッセージやパラメータを返却するか ・サービス実行結果が正しく画面に表示されるか ・非同期通信の実行結果が正しく画面に表示されるか |
||
EndToEndテスト | [BFF] ⇔ [Backend] | ・ユースケースシナリオ通り操作した時に、正しく画面に結果が表示されるか ・ユースケースシナリオ通り操作した時に、エラーメッセージが正しく表示されるか ・データベースへ正しくデータが反映できるか ・画面表示のレイアウトが崩れていないか ・ブラウザごとに表示が異なっていないか |
次回以降は、上記の観点に従い、SpringBootを使って、ControllerやService、Repositoryのテストの実装方法を解説していきます。
著者紹介
川畑 光平(KAWABATA Kohei) - NTTデータ 課長代理
金融機関システム業務アプリケーション開発・システム基盤担当を経て、現在はソフトウェア開発自動化関連の研究開発・推進に従事。
Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなどさまざまな開発プロジェクト支援にも携わる。2019 APN AWS Top Engineers & Ambassadors選出。