JCUnit
はJUnitの(サードパーティーの)テストランナーの1つで、
テストの入力となるフィールドにアノテーションをつけておくと、
そのアノテーションを元にしてPairwise法を使ってテストデータを自動生成して実行してくれる。
それはそれで便利なのだが、
今回はJCUnitのPairwiseのアルゴリズムを
JCUnitのテストランナー経由ではなくて直接切り出して使いたいと思ったので、
その方法を調べた。
import com.github.dakusui.jcunit.constraint.ConstraintManager;
import com.github.dakusui.jcunit.constraint.constraintmanagers.NullConstraintManager;
import com.github.dakusui.jcunit.core.Param;
import com.github.dakusui.jcunit.core.factor.Factor;
import com.github.dakusui.jcunit.core.factor.Factors;
import com.github.dakusui.jcunit.generators.IPO2TupleGenerator;
import com.github.dakusui.jcunit.generators.TupleGenerator;
public class Main {
public static void main(String[] args) {
ConstraintManager cm = new NullConstraintManager();
Factor os = new Factor.Builder().setName("OS")
.addLevel("Windows")
.addLevel("Linux")
.build();
Factor browser = new Factor.Builder().setName("Browser")
.addLevel("Chrome")
.addLevel("Firefox")
.build();
Factor bits = new Factor.Builder().setName("Bits")
.addLevel("32")
.addLevel("64")
.build();
Factors factors = new Factors.Builder().add(os).add(browser).add(bits).build();
TupleGenerator tg = new TupleGenerator.Builder()
.setTupleGeneratorClass(IPO2TupleGenerator.class)
.setConstraintManager(cm)
.setFactors(factors)
.setParameters(new Param[0])
.build();
tg.forEach(tuple -> System.out.println(tuple));
}
}
テストケースジェネレータとなるのはTupleGenerator型のオブジェクトである。
TupleGenerator.Builderのfluentなコンストラクタでオブジェクトを作る。
IPO2TupleGeneratorは生成されるTupleGeneratorの実装で、
IPOというのはPairwiseのアルゴリズムの一種のようだ。
ContaraintManagerは変数の組み合わせの制約を指定するためのもののようだが、
今回は何も制約をつけないのでNullConstraintManagerを与えている。
Factorsはテストケースの元となる一連の変数(Factor)の集まりである。
Factorは変数名と変数がとりうる値(level)から成る。
ParamはTupleGeneratorの実装固有のパラメタである。
ここでは何も指定しない(デフォルト)ので空の配列を与えている。
このParamというクラスは実際にはアノテーションクラスで、
普通はJUnitテストクラスに書かれたアノテーションがそのまま来るようだ。
もし今回のような使用方法でParamを指定するとしたら、
ちょっとまどろっこしい書き方をすることになると思う。
TupleGeneratorはIterable<Tuple>を継承しているので、
ここではforEachメソッドで生成結果を取得している。
TupleはMap<String, Object>を継承していて、キーが変数名、値が変数の値となる。
上記のコードの実行結果は次のようになる。
{Bits=32, Browser=Chrome, OS=Windows}
{Bits=64, Browser=Firefox, OS=Windows}
{Bits=64, Browser=Chrome, OS=Linux}
{Bits=32, Browser=Firefox, OS=Linux}
2つの値を持つ変数3つの組み合わせは単純に積を取ると8通りとなるが、
ここでは4通りのみ生成されている。
その一方で、任意の2つの変数の組み合わせはすべて登場するようになっている。
ご紹介&コメントありがとうございます。
お気づきかと思いますが、お使いのクラスは内部処理向けですので、少々まだるっこしい仕様のままでした。
最近、他の機能の実装でJCUnitのコードをいじることが多かったので、TupleGeneratorだけ使う人ももうちょっときれいに使えるように整理してみました。(0.5.4以降はこの仕様です)
# 思いの外、TupleGeneratorをダイレクトに使う人が多い、というのもありますが。
https://github.com/dakusui/jcunit#without-junit
https://github.com/dakusui/jcunit/blob/0.5.x/src/test/java/com/github/dakusui/jcunit/examples/testgen/TestGenWithoutJUnit.java
by dakusui (2015-10-05 21:26)
ご案内ありがとうございます。
公開APIというわけではないのだろうなというのは承知しているつもりでした。作者的に不本意(?)かもしれませんが、プログラムから使う場合は変数/レベルを動的に与えたいのでこういう使い方になったのです。
0.5.4以降の仕様は依存の件も含めてありがたい変更ですね。
by ether (2015-10-06 00:32)
不本意というよりは意外、というのが正直なところです。
もともとテストジェネレータだけ作っても何のためのものなのかわかる人がいないように思ったので、TestRunnerとして作ったというのが動機でしたので。
# いい機会なので、私のブログからもリンクいたしました。
by dakusui (2015-10-07 00:34)