テストツールAdventCalendar 2015 18日目の記事です。
#導入#
先日、ランダムデータを作ってテストしたいケースがあり、ランダムデータ生成やProperty-based testingのライブラリを探しました。
jPopulatorに続き、junit-quickcheckを試してみることにしました。
readmeを読みながら試してみます
#使い方#
まず、もっともシンプルな使い方です。
import com.pholser.junit.quickcheck.JUnitQuickcheck;
import com.pholser.junit.quickcheck.Property;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@RunWith(JUnitQuickcheck.class)
public class StringProperties {
@Property public void concatenationLength(String s1, String s2) {
assertEquals(s1.length() + s2.length(), (s1 + s2).length());
}
}
これでconcatenationLengthのテストが0~200文字のランダムな文字列で100回呼ばれます。
Generatorを指定して実行
@FromアノテーションでGeneratorのクラスを指定することでいろいろな値を生成することができます。
@RunWith(JUnitQuickcheck.class)
public class IdentificationProperties {
@Property public void shouldHold(@From(Version5.class) UUID u) {
// ...
}
}
カスタムGeneratorはcom.pholser.junit.quickcheck.generator.Generatorkurasu を実装するだけで作成できます。実装が必要なabstract methodはgenerate()メソッド一つなので簡単です。
import com.pholser.junit.quickcheck.generator.GenerationStatus;
import com.pholser.junit.quickcheck.generator.Generator;
import com.pholser.junit.quickcheck.random.SourceOfRandomness;
public class HogeGenerator extends Generator<String> {
public HogeGenerator() {
super(String.class);
}
@Override
public String generate(SourceOfRandomness random, GenerationStatus status) {
return "hoge";
}
}
@InRangeを使った生成データの範囲指定
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.junit.Assume.assumeThat;
import java.util.List;
import org.junit.runner.RunWith;
import com.pholser.junit.quickcheck.Property;
import com.pholser.junit.quickcheck.generator.InRange;
import com.pholser.junit.quickcheck.runner.JUnitQuickcheck;
@RunWith(JUnitQuickcheck.class)
public class SingleDigitProperties {
@Property
public void hold(@InRange(min = "0", max = "9") int digit) {
// hope we get enough single digits
assumeThat(digit, greaterThanOrEqualTo(0));
assumeThat(digit, lessThanOrEqualTo(9));
System.out.println(digit);
// ...
}
@Property
public void hold(List<@InRange(min = "0", max = "9") Integer> digits) {
System.out.println(digits);
// ...
}
}
assumeThat
今回試したときにはバグがあって正しく動作しなかった。
@When OGNL記法
@When(satisfies = "#_ >= 0 && #_ <= 9")
この記法は動作しなかった
その他
シンプルに回数指定
@Property(trials = 250) public void northernHemisphere(
Propertyにtrialsの値を渡すと指定した回数実施される。
Seed と Shrink
今回は時間がなくて試すことができなかった。
Readmeのサンプルコードで使っているHamcrest
HamcrestのMatherは2.0を使っている様子
まとめ
alphaバージョンだけあって、ドキュメント通りにやってみて動かない機能や、そもそも動かない機能があった。スマートに書けるので今後に期待したい。
今日は以上です。
次はFunctional-JavaのQuickcheckに挑戦する予定。