単体テスト時にdockerイメージを起動できる、GraldeのPluginであるgradle-docker-compose-plugin
を使いました。
サンプルプロジェクトとして、
dockerで起動したMockサーバーを使ってAPIアクセスの単体テストを作ってみます。
今回の目的は、HTTP経由でデータを取得するHTTP Clientの単体テストを行いたい
を解決することです。
成果物
sugasaki/gradle-docker-compose-test
使うもの
- IntelliJ Idea
-
avast/gradle-docker-compose-plugin
Gradleプラグインに追加することで単体テスト時にDockerを実行 -
Fuel
Kotlin用 HTTP Client -
MockServer
APIテストのためのMock Server
概要
HTTPからデータを取得する機能を単体テストする
- Gracleにgradle-docker-compose-pluginを追加
- Docker Composeファイルを設置(作成)
- 単体テストする
gradle-docker-compose-pluginのメモ
公式サイトを訳したものをメモとして残します。
Gradle環境でのローカル開発と統合テストのためのDocker Composeの使用を簡素化します。
composeUp
タスクはアプリケーションを起動し、すべてのコンテナが健全になり、公開されているTCPポートがすべて開くまで(アプリケーションの準備が整うまで)待ちます。特定のコンテナの割り当てられたホストとポートを読み込み、dockerCompose.servicesInfosプロパティに格納します。
composeDown
タスクは、'stopContainers' が 'true' (デフォルト値) に設定されている場合にのみ、アプリケーションを停止し、コンテナを削除します。
composeDownForced
タスクはアプリケーションを停止し、コンテナを削除します。
composePull
タスクは、アプリケーションが必要とする画像をプルし、オプションでビルドします。これは例えば、ビルド時間を短縮するためにdockerイメージをキャッシュするCIプラットフォームで有用です。
composeBuild
タスクはアプリケーションのサービスをビルドします。
composePush
タスクはサービスのイメージをそれぞれのレジストリ/リポジトリにプッシュします。
composeLogs
タスクはすべてのコンテナのログを containerLogToDir ディレクトリのファイルに保存します。
Quick start
依存関係に追加
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.avast.gradle:gradle-docker-compose-plugin:$versionHere"
}
}
apply plugin: 'docker-compose'
dockerCompose.isRequiredBy(test)
プラグイン指定
Gradle Portal プラグインを使用します (上記のように依存関係を追加する必要はありません)
plugins {
id 'com.avast.gradle.docker-compose' version "$versionHere"
}
- docker-compose upはプロジェクトディレクトリで実行されるので、docker-compose.ymlファイルを使用します。
- 提供されたタスク(上の例ではテスト)が新規プロセスを実行する場合、環境変数とJavaシステムのプロパティが提供されます。
- 環境変数の名前は${serviceName}_HOSTと${serviceName}TCP${exposedPort}です。(例: WEB_HOST, WEB_TCP_80)。
- Javaシステムプロパティの名前は${serviceName}.hostと${serviceName}.tcp.${exposedPort}です。(例: web.host と web.tcp.80)
- サービスがスケーリングされている場合、サービス名のサフィックスは _1, _2... です (例: WEB_1_HOST と WEB_1_TCP_80, web_1.host と web_1.tcp.80)
Why to use Docker Compose?
-
自分のコンピュータ上でアプリケーションを実行できるようにしたいし、同僚にも動作するようにしなければなりません。
docker-compose up
を実行するだけで完了します - 例えば、動作中のデータベース。 -
自分のコンピュータ上でアプリケーションをテストできるようにしたい - 自分のアプリケーションが開発/テスト環境にデプロイされ、受入れ/エンドツーエンドテストが実行されるまでは待ちたくありません。コンピュータ上でこれらのテストを実行したい - これらのテストの前に docker-compose up を実行することを意味します。
Why this plugin?
テストの前に docker-compose up
が呼ばれるようにするのは簡単ですが、このプラグインで解決できる問題がいくつかあります。
-
docker-compose up -d
(detached) を実行した場合、このコマンドはすぐに戻ります。このプラグインは、すべてのコンテナが健全な状態になり、すべてのサービスのエクスポートされた TCP ポートがオープンするまで待機します。 -
健全な状態になるまで待ったり、TCP ポートが開いている状態でタイムアウトした場合 (デフォルトは 15 分です)、関連するサービスのログを表示します。
-
docker-compose.yml で公開されているポートの固定値 (例: 8888:80) を指定しないことをお勧めします。ポートを公開する際に固定値を指定しない (80だけを使用する) と、ポートはランダムなフリーポートとして公開されます。このプラグインは、割り当てられたポート (コンテナの IP アドレスも) を読み込み、
dockerCompose.servicesInfo
マップに格納します。 -
Linux、Windows、MacでLinuxコンテナを使用している場合と、Windowsコンテナを使用している場合では、細かな違いがあります。このプラグインはこれらの違いを処理してくれるので、 どの環境でも同じ経験をすることができます。
Tips
-
dockerCompose.isRequiredBy(anyTask)を任意のタスク、例えばカスタムのintegrationTestタスクに対して呼び出すことができます。
-
あるDockerfileがGradleによって生成されたアーティファクトを必要としている場合は、
composeUp.dependOn project(':my-app').distTar
のように、標準的な方法でこの依存関係を宣言することができます。 -
dockerCompose
のすべてのプロパティは意味のあるデフォルト値を持っているので、触る必要はありません。興味のある方はComposeSettings.groovy
を参考にしてみてください。 -
dockerCompose.servicesInfos
には実行中のコンテナに関する情報が含まれているので、composeUp
タスクが終了した後にこのプロパティにアクセスする必要があります。そのため、テストタスクのdoFirstはこのプロパティにアクセスするのに最適な場所です。 -
プラグインは
docker-compose.override.yml
ファイルを尊重しますが、useComposeFiles
でファイルが指定されていない場合に限ります(コマンドラインの動作に準拠します)。 -
ContainerInfo.groovy
をチェックして、コンテナの実行について知ることができます。 -
GradleのビルドでDockerホストを決定し(つまりdocker-machine起動)、composeで使用する環境変数DOCKER_HOSTを設定することができます:
dockerCompose { environment.put 'DOCKER_HOST', '192.168.64.9'}
-
docker-compose
で実行されるサービスが特定のホスト(CirceCI 2.0のようにDockerとは異なる)で実行されている場合は、環境変数services_host
を使用することができます。この値は、サービスが待ち受けていると予想されるホスト名として使用されます。
Fuel
割愛します