ユニットテストを気軽にわかりやすく書くための一提案
これまでに公開しているオープンソースのコードを見て貰えばわかるのだが、ここに付属しているユニットテストは通常「こうやれ」というやり方では記述していない。そんな必要は無いし、この方が便利だと思うからである。これについて解説する。
皆さんが従っている馬鹿馬鹿しい「ディレクトリ分割作法」について
ソースディレクトリについては、以下のような構成が「良い」とされているようだ。これはMavenビルドシステムから始まっているものと思うが、私には定かではない。
src
+- main
+- java
+- com
+- cm55
+- resources
+- test
+- java
....
すなわち、基本的には開発対象のJavaソースとユニットテストソースを完全に分離させるのである。つまり、Sample.javaという製品用のクラスと、それをテストするSampleTest.javaは全く異なるディレクトリ階層の中に置かれることになる。
私の方法
ソースを見てもらえばわかるのだが、当方ではこんなことはしない。Sample.javaとSampleTest.javaは「隣どうし」に置かれている。例えば、EventBusのソースを見ていただきたい。以下のように製品用クラスと、それをテストするクラスはおおよそ隣どうしに配置されている。
こうすれば、製品用クラスを修正したときにも、それがどこでテストされているのかがすぐわかるし、すぐ修正できることになる。
そして、同じパッケージ内にあるこれらすべてのテストをAllTestでまとめている。以下のコードだ。
package com.cm55.eventBus;
import org.junit.runner.*;
import org.junit.runners.*;
import org.junit.runners.Suite.*;
@RunWith(Suite.class)
@SuiteClasses( {
CallerStackTest.class,
EventBusTest.class,
EventBusEventTypeTest.class,
EventTypeTest.class,
ListenerHolderTest.class,
UnlistenerTest.class
})
public class AllTest {
public static void main(String[] args) {
JUnitCore.main(AllTest.class.getName());
}
}
製品からユニットテストを除去する方法
「これでは製品にもユニットテストが残ってしまうんじゃ?」と思うかもしれないが、そんなことは無い。なぜならソースセットを以下のように指定しているからだ(build.gradle)。
sourceSets {
main {
java {
srcDir 'src'; exclude '**/*Test.java'
}
resources {
srcDir 'src'; exclude '**/*Test.java'
}
}
}
ビルド対象からすべての*Test.javaを除去してしまう。唯一の問題と言えば、「なんちゃらTest」というクラスは作れないことのみだ。ソースコードに関しては、これ以外の問題は無い。
Eclipseの環境設定
唯一問題となるのは、Gradleのeclipseプラグイン(EclipseのGradleプラグインではない)を使用して、build.gradleのsourceSetsをEclipseの.classpathファイルを自動生成させていることだ。つまり、sourceSetsに記述した内容をEclipseのJava Build PathのSource部分に記述されるのだが、このとき*Test.javaというファイルが除外されてしまい、そのままではEclipse上でも*Test.javaファイルがJavaソースとして認識されない。
※上は非常にややこしい記述だが、これ以外に書きようがない。
これを避けるためには、build.gradleに仕掛けを施しておく必要がある。これは既にEclipseClasspathの使い方に記述してあるので参照されたい。
ディスカッション
コメント一覧
まだ、コメントがありません