Hansel
Hansel
公式サイト
ここでは、Hansel 1.02とBCEL 5.1を用いていろいろと試しています。
ヘンゼルとグレーテルでコードをカバーするにて詳しく記載されています(というか、そのページで初めて存在を知ったのですが)。
特徴
- Javaプログラムのカバレージツールの1つ。
- JUnitのテストケースに数行記述するだけで、カバレッジテストを行うことができます。
- Eclipseの場合は、Hansel用のコードを追加したテストケースを、Run AsでJUnit Testを指定して実行することになります。
サンプル
内容も何もあったもんじゃないサンプルクラスです(笑)。public class SampleClass { public void execute(boolean flag, String value) { if (flag) check(value); System.out.println("何らかの処理を行います"); } public void check(String value) { System.out.println("何らかのチェックを行います"); } }これに対して以下のようなJUnitテストケースを作成。正確にはテストを行っているわけではないのでテストケースとは呼べませんが。
import junit.framework.TestCase; public class SampleClassTest extends TestCase { public void testExecute() throws Exception { SampleClass sample = new SampleClass(); sample.execute(false, "Something"); } }これを実行した場合、テストは通ります。何もassertしていないので当然ですが(笑)。で、このテストケースにHanselを組み込むと、以下のような感じになります(メソッドsuite()を用いて、テストスイートとしてテストを実行することになります)。
import org.hansel.CoverageDecorator; import junit.framework.Test; import junit.framework.TestCase; public class SampleClassTest extends TestCase { public void testExecute() throws Exception { SampleClass sample = new SampleClass(); sample.execute(false, "Something"); } public static Test suite() { return new CoverageDecorator( SampleClassTest.class, new Class[] { SampleClass.class } ); } }このテストケースを実行すると、以下のようなFailureとともにテストが失敗します。
Probe in "SampleClass.java" line 3
Coverage failure: Branch not completely covered. Condition '!(flag == 0)' is not fulfilled.
at SampleClass.execute(SampleClass.java:3)
Probe in "SampleClass.java" line 7
Coverage failure: Method not covered.
at SampleClass.check(SampleClass.java:7)
1つ目は「3行目のif文においてtrueの場合がテストされていない」ということを、2つ目は「checkメソッドが実行されていない」ということを意味しています。逆に、trueの場合のみをテストした場合は、
Probe in "SampleClass.java" line 3
Coverage failure: Branch not completely covered. Condition 'flag == 0' is not fulfilled.
at SampleClass.execute(SampleClass.java:3)
というようなFailureとともにやはりテストは失敗します。これは先ほどとは逆に「3行目のif文においてfalseの場合がテストされていない」ってことになります(結果の英文がわかりにくいですが・・・)。なので、引数をtrueにした場合とfalseにした場合のexecuteメソッドを実行すれば、とりあえずテストケースは成功することになります。
まぁ、このサンプルは正確にはテストではありませんでしたが、実際にはいろいろなJUnit用のテストケースにHanselを組み込んでカバレッジテストを行いながら開発を行うことになります。
補足
テスト対象となるクラスが複数ある場合
テスト対象のクラスがあるクラスのサブクラスの場合で、そのスーパークラスもカバレッジ測定の対象としたい場合は、suite()メソッドで以下のようなCoverageDecolatorを戻します。new CoverageDecorator(SubClassTest.class, new Class[] { SubClass.class, SuperClass.class })
djUnitとの併用
CoverageDecoratorを組み込んだテストケースをdjUnitで実行した場合、予期せぬ結果が得られてしまう場合があります。また、Hanselを用いた場合、カバレッジが100%でないと問答無用でテストケースが失敗してしまうため、場合によっては一時的にHanselを外したい場合もあるかもしれません。その場合、suite()メソッドを毎回コメントアウトするのも面倒なので、通常のテストケースとHansel用のテストケースを分けると楽かもしれません(CoverageDecoratorを作成する際に、実行するテストケースを第1引数で指定するため、別々に存在することが可能になっています)。import junit.framework.TestCase; public class SampleClassTest extends TestCase { public void testExecute() throws Exception { SampleClass sample = new SampleClass(); sample.execute(false, "Something"); } }というテストケースと、これに対してHanselを適用した
import org.hansel.CoverageDecorator; import junit.framework.Test; import junit.framework.TestCase; public class SampleClassTestHansel extends TestCase { public static Test suite() { return new CoverageDecorator( SampleClassTest.class, new Class[] { SampleClass.class } ); } }を準備しておいて、必要に応じて実行するテストケースを切り替えるような感じです。
J2SE5.0での使用
Genericsを用いていた場合に、ClassFormatErrorが発生してテストが実行できない場合があるようです(細かい条件までは調べていませんが)。2006年06月11日(日) 11:51:10 Modified by syo1976