こんにちわ、みけです。
某社で一日中ドラクエやってて、
何の成果もあげていません。
…
あ、いや、そんなことはどうでもいいです。
いや、よくないか。
インテグレーションテストとは…
とりあえず、ここでは、乱暴な言い方ですが、
ソフトウェアの機能に対して期待している動作を
検証するテストということにしておきましょう。
(一つのオブジェクトレベルでの動作ではないことに注意)
ここで、「とりあえず」「ここでは」としたわけですが、
実際のプロジェクトにおいては、
このフェーズのテストは何を保証するべきである
というのは、それぞれのプロジェクトで
議論して決めるべきだと思っています。
インテグレーションテストを実行するにあたって、求められるプロジェクト構造
ここでいうプロジェクト構造とは、
プロジェクトマネージャーは◯◯課長で…
とかいう話ではありません。
書いたコードをどのディレクトリーに配置するかという話です。
求められる構造は次のとおりです。
- 同じプロジェクトにある
- プロダクションコードとは別の場所にある
- ユニットテストとは別の場所にある
というわけで、まあ、project-root/src
の下に
main
とtest
とは別のディレクトリーを作成するのがよいでしょう。
すると、プロジェクトの構造は次のようになります。
project-root └─src ├─integTest │ └─java │ └─…(以下略)… ├─main │ ├─java │ │ └─…(以下略)… │ └─resources │ └─…(以下略)… └─test └─java └─…(以下略)…
project-root/src/integTest/java
インテグレーションテストを配置するディレクトリー
project-root/src/main/java
プロダクションコードを配置するディレクトリー
project-root/src/main/resources
プロダクション用のリソースを配置するディレクトリー
project-root/src/test/java
ユニットテストを配置するディレクトリー
インテグレーションテストの設定
多分、今回の話のメインはここです。
ポイントとしては以下のとおりです。
- インテグレーションテスト用の
configurations
を追加する - インテグレーションテスト用の依存ライブラリーを指定する
- インテグレーションテストタスクを設定する
インテグレーションテスト用のconfigurations
を追加する
configurations
を追加するだけなら、次のように書けます。
configurations { additionalConfiguration }
ただ、ここではテスト用のconfigurations
の追加なので、
sourceSets
への追加が必要となってきます。
したがって、configurations
に記述するのではなくて、
次のようにsourceSets
に記述します。
sourceSets { integTest { java.srcDir file('src/integTest/java') resources.srcDir file('src/integTest/resources') } }
インテグレーションテスト用の依存ライブラリーを指定する
先ほどのsourceSets
への追加によって、
自動でconfigurations
にintegTest
というconfiguration
が追加されます。
そこに必要な依存性を記述していきます。
また、integTest
がプロダクションコードへ依存する場合、
プロダクションコードに依存するということを記述しておかないとなりません。
repositories {
mavenCentral ()
}
dependencies {
integTestCompile 'junit:junit:4.11'
integTestCompile sourceSets.main.output
}
Spockを使いたい場合などは、別途Spockやgroovy-allなども
追加しておいたほうがよいでしょう。
インテグレーションテストタスクを設定する
Test
タイプのタスクを追加します。
task integTest(type : Test) { testClassesDir = sourceSets.integTest.output.classesDir classPath = sourceSets.integTest.runtimeClasspath }
ここまでまとめ
以上の結果をまとめたbuild.gradle
の記述は次のようになります。
apply plugin : 'java' sourceCompatibility = 1.8 targetCompatibility = 1.8 sourceSets { integTest { java.srcDir file('src/integTest/java') resources.srcDir file('src/integTest/resources') } } repositories { mavenCentral () } dependencies { compile 'org.slf4j:slf4j-api:1.6.6' compile 'ch.qos.logback:logback-core:1.0.7' compile 'ch.qos.logback:logback-classic:1.0.7' testCompile 'junit:junit:4.11' integTest 'junit:junit:4.11' integTest sourceSets.main.output } task integTest(type : Test) { testClassesDir = sourceSets.integTest.output.classesDir classPath = sourceSets.integTest.runtimeClasspath }
インテグレーションテストの実行
後はテストを書いて実行するだけです。
インテグレーションテストはintegTest
タスクで行います。
$ gradle integTest :compileJava :processResources :classes :compileIntegTestJava :processIntegTestResources :integTestClasses :integTest BUILD SUCCESSFUL Total time: 12.305 secs
だいたいこのように表示されると思います。
なお、もしもユニットテストで使っている超便利クラスなどがあって、
インテグレーションテストでもそれを利用したい場合は、
インテグレーションテストからユニットテストの成果物への参照も
できる用に設定しておく必要があります。
この場合は依存性解決部分に次のような記述を追加するとよいでしょう。
dependencies { integTest sourceSets.test.output }
インテグレーションテストのコンパイルが実行されます。
もし、IDEなどで自動的に参照してしまってた場合は、
参考にしてみてください。
以上