こんにちわ、みけです。
某社で一日中ドラクエやってて、
何の成果もあげていません。
…
あ、いや、そんなことはどうでもいいです。
いや、よくないか。
インテグレーションテストとは…
とりあえず、ここでは、乱暴な言い方ですが、
ソフトウェアの機能に対して期待している動作を
検証するテストということにしておきましょう。
(一つのオブジェクトレベルでの動作ではないことに注意)
ここで、「とりあえず」「ここでは」としたわけですが、
実際のプロジェクトにおいては、
このフェーズのテストは何を保証するべきである
というのは、それぞれのプロジェクトで
議論して決めるべきだと思っています。
インテグレーションテストを実行するにあたって、求められるプロジェクト構造
ここでいうプロジェクト構造とは、
プロジェクトマネージャーは◯◯課長で…
とかいう話ではありません。
書いたコードをどのディレクトリーに配置するかという話です。
求められる構造は次のとおりです。
- 同じプロジェクトにある
- プロダクションコードとは別の場所にある
- ユニットテストとは別の場所にある
というわけで、まあ、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などで自動的に参照してしまってた場合は、
参考にしてみてください。
以上