読者です 読者をやめる 読者になる 読者になる

mike-neckのブログ

JavaかJavaFXかJavaEE(なんかJava8が多め)

Kotlin用のjunit-quickcheck風なテスティングフレームワークを作った

表記のとおりです。

テストデータをランダムに自動生成して複数回実行させるというライブラリーです。調べてみたところ、Kotlin用のものがないようなので、作ってみました。名前はKuickCheckという名前にしていますが、今後どうなるかわかりません。あと、僕は残念ながらProperty based testingに詳しくありませんし、QuickCheckとかScalaCheckとかScalaPropのこともよく知りません(不勉強)。

github.com

入手方法

Mavenにあがっています。

<dependency>
    <groupId>org.mikeneck</groupId>
    <artifactId>kuickcheck-core</artifactId>
    <version>0.1</version>
    <scope>test</scope>
</dependency>
  • Gradle
dependency {
  testCompile 'org.mikeneck:kuickcheck-core:0.1'
}

依存ライブラリーはkotlin-runtimeとkotlin-reflectだけです。

JUnitにまったく依存していないので、Junitとともに走らせることはできません。

テストの書き方

テストの書き方はシンプルです。

  1. クラスかオブジェクトを作成します。
  2. forAllメソッドにチェックしたいデータを指定します(下のサンプルでは正のintであるpositiveIntを指定しています)。
  3. チェックする性質をsatisfy{}ブロックに記述します。
  4. 1-3によって返されるオブジェクトをなんらかのメンバーに指定します。このメンバーにはテストする性質がわかるような名前をつけます。
  5. 4.に対して@Propertyアノテーションを付与します。

これにより、ランダムな値でデフォルトで100回のテストを実行します。

object GettingStarted {

  @Property
  val positiveNumberIsMoreThan0 =
      forAll(positiveInt).satisfy{ it > 0 }

  @Property
  val `positiveInt x negativeInt becomes negative` =
      forAll(positiveInt, negativeInt).satisfy {l,r -> l * r < 0}
}

テストの実行

テストの実行は今のところjava -jarによる実行方法しかありません。頑張って作成したテストのjar、kotlin-runtime.jar、kotlin-reflect.jar、kuickcheck.jarを集めて、org.mikeneck.kuickcheck.KuickCheckをメインに指定して実行します。Gradleを使っている場合はJavaExecタスクで実行するのがよいでしょう。

f:id:mike_neck:20160613164251p:plain

実行すると、このような形で成功したテストが緑、失敗したデータが有る場合は赤、例外が発生した場合は黄で表示されます。

Javaとのinterop

試していないのでわかりません(´・ω・`)

intとかlongとかJavaのプリミティブ型と同じ名前のAPIを準備しているのでコンパイルできないのではないかと思います。

この後

一応、今のところできているのは

  • パッケージをスキャンしてテストを抽出
  • intlongBigIntegerなどの基本的な型の値を自動で生成してテストに流す
  • テスト結果をコンソールに表示

です。

できていないところは

  • テスト結果をファイルに吐き出す
  • Ktで終わるソースを検知できない(Ktファイルを除外するために末尾がKtのものを除外している)
  • JUnitに依存していないので、JUnitとともに走らせることができない

などなどです。