はじめに
こんにちは、マイグレーションチームの寺嶋です。
本記事では、ZOZOTOWNのマイクロサービスにおけるデータベースを参照したユニットテストの改善で得られた知見や工夫について紹介します。
背景と課題
ZOZOTOWNでは、数年前からリプレイスプロジェクトが実施されており、いくつものマイクロサービスが誕生しました。初期にJavaで作られたマイクロサービスのユニットテストが開発環境のデータベースを参照しており、テストで利用しているデータが更新・削除されてしまうとテストに失敗してしまうことが度々起きていました。また、接続しているデータベースがオンプレのSQL Serverを利用しており、CI上でユニットテストを実施できない状況でした。
そのため対象のユニットテストは次の問題を抱えていました。
- ローカルPC上でしか実行できない
- 実データを利用しているので今日通ったテストが明日落ちる(可能性がある)
このようなことから外部環境に依存しないユニットテストへ変更する必要がありました。
対象サービスの技術スタック
今回改善するマイクロサービスの技術スタックは次の通りです。
- Java 11
- Maven
- Spring Boot
- MyBatis
- SQL Server
- JUnit 4
ZOZOTOWNリプレイスプロジェクトでは全社技術スタックを統一しています。詳しくは下記の記事をご覧ください。

ZOZO開発組織の2021年の振り返りと現状 - Qiita
対応方法の検討
解決方法として次の方法を検討しました。
- H2データベースを利用する
- Dockerコンテナのデータベースに接続する
H2データベースはJVM上にて動作するデータベースでインストールを必要としません。JDBCのURLに ;MODE=MySQL といったオプションをつけることでH2データベースの挙動をMySQL、PostgreSQLなど切り替えることができます。もちろんSQL Serverモードもあり、 ;MODE=MSSQLServer を指定すればSQL Server風の挙動を再現させることが可能になります。ただ、H2のドキュメントを確認していると、 ヒント句は破棄される という説明があり、SQLチューニングでヒント句を使用しているサービスなので、採用は見送ることになりました。
ということで、DockerコンテナでSQL Serverを起動させてテストする方法となり、見つけたのが Testcontainers でした。
Testcontainersとは
TestcontainersはJUnitのテストをサポートするJavaライブラリです。一般的なデータベースやSelenuim、Dockerコンテナで実行できるものを軽量で使い捨て可能なインスタンスとして提供してくれます。Testcontainersを利用すると次の種類のテストが簡単に行えます。
データアクセスレイヤーテスト
MySQL、PostgreSQL、Oracle Databaseなどのコンテナ化されたインスタンスを使用して、データアクセスレイヤーにコードの変更なくテストを実行できます。Dockerコンテナを利用するので複雑なセットアップも必要ありません。
アプリケーション統合テスト
データベース、メッセージキュー、Webサーバなどの依存関係を使用してアプリケーションのテストを実行できます。
UI受け入れテスト
自動化されたUIテストを実施するためにSelenuimと互換性のあるコンテナを使用し、ブラウザの状態やバージョンを気にすることなくテストを実施できます。また、失敗したテストのみ動画を録画するなども行ってくれます。
今回は データアクセスレイヤーテスト を活用して、実データベースを参照しているテストを改善します。
開発環境のデータベースから切り離す
pom.xml
Testcontainersの依存関係をpom.xmlに追記していきます。今回はSQL Serverコンテナをユニットテスト時に起動しますのでorg.testcontainers.mssqlserverを追加しています。MySQLやPostgreSQL、Oracle Databaseを利用する場合は対象データベースのdependencyがありますので、環境に応じて指定してください。
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.16.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mssqlserver</artifactId>
<version>1.16.3</version>
<scope>test</scope>
</dependency>SQL Serverコンテナの起動
MSSQLServerContainerクラスがSQL Serverコンテナを管理するクラスとなっており、これを継承し新たにMyMSSQLContainerクラスを作っていきます。
続きはこちら