9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaでProperty-Based testing その1 [JPopulator + Junit]

Last updated at Posted at 2015-12-12

テストツールAdventCalendar 2015 11日目の記事です。
1日遅れてしまってすいません。

#導入#
先日、ランダムデータを作ってテストしたいケースがあり、ランダムデータ生成やProperty-based testingのライブラリを探しました。
そこで見つけたjPopulatorが簡単に使えて便利そうだったので紹介しようと思います。

#使い方#
まず、もっともシンプルな使い方です。

Populator generator = new PopulatorBuilder().build();
generator.populateBean(Person.class);

populateBeanメソッドの引数に指定したクラスのデータが自動的に生成できます。
他のフレームワークに依存しておらず、たったこれだけの記述でランダムデータを生成できます。
また、フィールドにクラスがある場合も自動的にそのクラス内のフィールドもランダムデータで埋めてくれます。

普段テストするとき、本当はできるだけ現実で使われるデータに近いデータを用意したいのに、必要最低限で済ますことが多いかと思います。
簡単に記述できるるので、テストの視認性を下げずに、重要度が低いと考えているフィールドにもとりあえず値を詰めておくということができます。

##生成データのコントロール##
生成データを調整することも簡単にできます。
###フィールドを除外して生成###
generator.populateBean(Person.class, "age");

###指定数のインスタンスをまとめて作成###
generator.populateBeans(Person.class, 100);

###ランダムな数のインスタンスをまとめて作成###
generator.populateBeans(Person.class);

##生成されるデータのバリエーションを変える##
Randomizerインターフェースを実装することで生成データの内容も自由にカスタマイズできます。

public class AgeRandomizer implements Randomizer<Integer> {
    @Override
    public Integer getRandomValue() {
        return ((Double) (Math.random() * 50)).intValue();
    }
}

RandomizerはSAM Typeなのでもちろんラムダ式で書くことができます。

Populator generator = new PopulatorBuilder()
                .registerRandomizer(Person.class, Integer.class, "age", () -> ((Double) (Math.random() * 50)).intValue())
                .build();
}

既成のRandomizerもいくつか用意されているので便利に使えると思います。

既成のRandomizer
スクリーンショット 2015-12-12 13.56.40.png

Randomizerの使用例

Populator generator = new PopulatorBuilder()
                .registerRandomizer(Person.class, String.class, "name", new FirstNameRandomizer())
                .build();

最後にテストへの応用例としてJUnitのDataPointsを利用してテスト用のランダムデータを生成するコードを紹介します。

import org.junit.contrib.theories.DataPoints;
import org.junit.contrib.theories.Theories;
import org.junit.contrib.theories.Theory;
import org.junit.runner.RunWith;

import io.github.benas.jpopulator.api.Populator;
import io.github.benas.jpopulator.impl.PopulatorBuilder;
import io.github.benas.jpopulator.randomizers.CityRandomizer;
import io.github.benas.jpopulator.randomizers.FirstNameRandomizer;

@RunWith(Theories.class)
public class UseJpopulator {
    @DataPoints
    public static Person[] getParameters() {
        Populator generator =
            new PopulatorBuilder()
                .registerRandomizer(Person.class, String.class, "name", new FirstNameRandomizer())
                .registerRandomizer(Person.class, Integer.class, "age", () -> ((Double) (Math.random() * 50)).intValue())
                .registerRandomizer(Address.class, String.class, "city", new CityRandomizer())
                .build();
        return generator.populateBeans(Person.class, 100).toArray(new Person[0]);
    }
    @Theory
    public void XXX(Person p) {
        // TODO some tests
    }
}

生成結果
スクリーンショット 2015-12-12 14.06.32.png

今日は以上です。

次はJunit-Quickcheckについて書くつもりです。

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?