SSブログ

JCUnitのテストケースジェネレータを切り出して使う [Java]

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つの変数の組み合わせはすべて登場するようになっている。


nice!(0)  コメント(3)  トラックバック(0) 

nice! 0

コメント 3

dakusui

ご紹介&コメントありがとうございます。
お気づきかと思いますが、お使いのクラスは内部処理向けですので、少々まだるっこしい仕様のままでした。

最近、他の機能の実装で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) 

ether

ご案内ありがとうございます。

公開APIというわけではないのだろうなというのは承知しているつもりでした。作者的に不本意(?)かもしれませんが、プログラムから使う場合は変数/レベルを動的に与えたいのでこういう使い方になったのです。

0.5.4以降の仕様は依存の件も含めてありがたい変更ですね。
by ether (2015-10-06 00:32) 

dakusui

不本意というよりは意外、というのが正直なところです。
もともとテストジェネレータだけ作っても何のためのものなのかわかる人がいないように思ったので、TestRunnerとして作ったというのが動機でしたので。

# いい機会なので、私のブログからもリンクいたしました。
by dakusui (2015-10-07 00:34) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。