はじめに

Property-based Testing というものを知ったので, Java でできるか試してみました.

Property-based Testing とは

うまい日本語訳がないのだが, この記事では性質テストとする.

ある集合のなかにある要素から取り出した値をつかって, 総当たりテストをして, 条件式がなりたつことを確認するテスト.

よく数学の問題で, 任意の x について hogehoge がなりたつことを証明せよ みたいなのがあるが, hogehoge が 性質にあたるもの.

上手く説明できないので, 大量の参照リンクをはっておく.

英語:

ScalaCheck

Scala の 性質テスト用ツールで, ScalaCheck というものがある.

Scala なので, Java にもつかえるか試す.(私は, 現在 java プログラマなので)

target

以下のコードをテスト.

package example;

public class MyArithmetic {
	public static int add (int a, int b) { return a + b; }
	public static int del (int a, int b) { return a - b; }

	public static void main (String[] args) {
		System.out.println (add (1, 2));
	}
}

Java で sbt をつかう

scala のテストツールなので, scala の ビルドツール sbt をつかうのが楽.

src/main/java 配下に ソースをおいて, root で sbt を起動すると なんと Java コードが sbt で使えてしまう.

これはこれで, 手軽さに驚いた. Java のビルドツールとして使えそう.

# コンパイル
> compile

# main 関数を自動で検索して実行
> run

ScalaCheck をつかう

以下のようなファイルを作成して, src/test/scala 配下におく.

import org.scalacheck.Properties
import org.scalacheck.Prop.forAll

import example._

object MyArithmeticSpecification extends Properties ("MyArithmetic") {

  property ("add") = forAll { (a : Int, b : Int) =>
    val aa = a % 100
    val bb = b % 100
    val c = MyArithmetic.add (aa*aa, bb*bb)
    c >= aa*aa && c >= bb*bb
  }

  property ("add2") = forAll { (a : Int) =>
    val aa = a % 100
    aa * aa >= aa
  }

  property ("del") = forAll { (a : Int, b : Int) =>
    val aa = a g% 100
    val bb = b % 100

    val c = MyArithmetic.del (aa*aa, bb*bb)

    c <= aa*aa || c <= bb*bb
  }
}

root ディレクトリの build.sbt に以下を書く.

libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.2" % "test"

ファイル構成はいかのようなかんじ

--- build.sbt
    src
       main
           java
               MyArithmetic.java
    test
           scala
               MyArithmeticSpecification.scala

テスト実行

$ sbt test
[info] + MyArithmetic.add: OK, passed 100 tests.
[info] + MyArithmetic.add2: OK, passed 100 tests.
[info] + MyArithmetic.del: OK, passed 100 tests.
[info] Passed: Total 3, Failed 0, Errors 0, Passed 3
[success] Total time: 1 s, completed 2015/04/18 17:54:54

おわりに

むかしむかし, CUnit のことを課長にはなしたことがあったのだが, (うたぐり深い) 課長は, xUnit のようなものでは品質がとれないと突っかかってきた.

全部網羅したテストじゃないと, 完全にバグがないなんて言いきれない

自分はこれに対して反論ができなかった.

いまならば, 反論できる.Property-based Testing はどうだろう? 乱数による総当たりテストならば, 信じてくれるのではないだろうか?