Jumble使ってみた

すげー面白い。
プラグインもあるので、さくっと試せるし。
というわけで、簡単にまとめてみる。


概要
  • Jumbleとは

作成したテストケースの有効性を検証するツール。
テストケースの点数を0%(悪い)から100%(良い)の値で出力する。

  • どーやって検証するのか

テスト対象クラスを動的に変更しながら既存のテストケースを流して判定する(っぽい)。
テスト対象クラスを変更してもテストケースが失敗しない場合、いけてないテストケースとなる。

  • クラスの変更箇所

クラスの次のようなポイントを変更する。

    • 条件
    • 二項演算子
    • インクリメント・デクリメント
    • インライン定数
    • コンスタントプールの定数(って表現はびみょー?)
    • 戻り値
    • Switch文

条件と二項演算子以外は、オプションで任意に指定できる。

サンプル

まずはテスト対象クラス。
# 拡張子を返却するようなどーでもいいロジック。
# 一部いけてないのはわざと。

public class Target {
    public String exec(String str) {
        if (str == null || !str.contains(".")) {
            return null;
        }
        
        int index = str.lastIndexOf(".");
        return  str.substring(index + 1);
    }
}


テストケース。
テストはnullの場合のみ。

public class TargetTest extends TestCase {
    public void test01() {
        String result = new Target().exec(null);
        assertNull(result);
    }
}


Jumbleを実行した結果(改行&項番は説明用に自分で付けた)。

Mutating jp.gr.java_conf.ykhr.test.Target
Tests: jp.gr.java_conf.ykhr.test.TargetTest
Mutation points = 7, unit test time limit 2.0s
M FAIL: jp.gr.java_conf.ykhr.test.Target:5: CP[16] "." -> "___jumble___"     --- 1
.
M FAIL: jp.gr.java_conf.ykhr.test.Target:5: negated conditional              --- 2
.
M FAIL: jp.gr.java_conf.ykhr.test.Target:10: 1 -> 0                          --- 3
M FAIL: jp.gr.java_conf.ykhr.test.Target:10: + -> -                          --- 4
M FAIL: jp.gr.java_conf.ykhr.test.Target:10: changed return value (areturn)  --- 5

Score: 28%


今回のテストケースのスコアは28%。
以下の変更をしたときに、テストケースクラスがその変更を検出できなかったと
言っているっぽい。

  1. "."を"___jumble___"に変えた
  2. 条件文の結果を逆にした
  3. 「index + 1」の1を0にした
  4. 「index + 1」の+を-にした
  5. 戻り値を変更した


↓のようなちゃんとしたテストケースクラスだと、100%になります。

public class TargetTest extends TestCase {
    
    public void test01() {
        String result = new Target().exec(null);
        assertNull(result);
    }
    
    public void test02() {
        String result = new Target().exec("");
        assertNull(result);
    }
    
    public void test03() {
        String result = new Target().exec("abc.txt");
        assertEquals("txt", result);
    }
    
}
おまけ

例えば、「new StringBuffer(20);」なんてのがあると、
20を変更してもテストケースクラスは失敗しないので、
スコアが落ちてしまう。
オプションで変更しないようにもできるけど。

おまけ2

Web上でJumbleを動かせるようなCGIがついてくるけど、なんかうまく動かなかった。
これは、自分が環境周りの知識が弱いせいです・・・。

おわり

テストケースがちゃんと実装できているかを知るようなツールって、
今までだとカバレッジ計測ツールくらいしかなかったと思う。
ただ、カバレッジだとテストケースの検証部分を実装していなくても
普通の値が出てしまったりする。
なので、これを1つのメトリクスとして採用してもよさそーな気がする。


というか、テストケースを評価するのに、こんな方法を思いつくことがすげー。
# あと、よくこんなのを作ろうと思ったよなぁと。