Groovy + Spock でデータドリブンテスト



Javaプログラムのテストコードを書くとき、Unittestだとパターンを網羅できているかわかりづらかったので、美しいテストコードを書くためにGroovyとSpockを使って書いてみました。


*Groovyとは

Javaベースのスクリプト言語で、Javaとの親和性が高く、Javaのコードに修正を加えなくてもGroovyファイルに変換することができます。
また、型の定義や面倒なMapの書き方を省略できるので、Javaよりも短い記述が可能です。
(参考:Groovy


*Spockとは

JavaとGroovy用のテストフレームワークで、データドリブンテストとモック機能が充実しています。
(参考:Spock


*FizzBuzz

簡単なFizzBuzzプログラムで試してみます。
/**  
 * FizzBuzz 
 * - 3で割れる数:Fizz 
 * - 5で割れる数:Buzz 
 * - 3と5で割れる数:FizzBuzz 
 */
 public class FizzBuzz {  
    public String fizzBuzz(int num) {  
        if (num % 3 == 0 && num % 5 == 0) {  
            return "FizzBuzz";  
        } else if (num % 3 == 0) {  
            return "Fizz";  
        } else if (num % 5 == 0) {  
            return "Buzz";  
        } else {  
            return String.valueOf(num);  
        }  
    }  
}

<Java + Unittest>

これをUnittestを使って書いてみました。パターンごとにテストを書かなければいけないので、見づらいかと思います。
import org.junit.Test;  
import static org.junit.Assert.*;

public class FizzBuzzUnitTest {  
  
    public static class 正常系 {  
        FizzBuzz fizzBuzz = new FizzBuzz();  
  
        @Test  
        public void 引数が1の場合は1を返す() {  
            assertEquals("1", fizzBuzz.fizzBuzz(1));  
        }  
  
        @Test  
        public void 引数が3の場合はFizzを返す() {  
            assertEquals("Fizz", fizzBuzz.fizzBuzz(3));  
        }  
  
        @Test  
        public void 引数が5の場合はBuzzを返す() {  
            assertEquals("Buzz", fizzBuzz.fizzBuzz(5));  
        }  
  
        @Test  
        public void 引数が15の場合はFizzBuzzを返す() {  
            assertEquals("FizzBuzz", fizzBuzz.fizzBuzz(15));  
        }  
    }
}

<Groovy + Spock>

GroovyとSpockを使って書くと、Unittestよりもシンプルに書くことができ、パターンを網羅していることが一目でわかるようになります。
import spock.lang.Specification  
import spock.lang.Unroll  
  
class FizzBuzzTest extends Specification {  
  
  @Unroll  
  def "FizzBuzzのテスト_#num"() {  
        setup:  
        def sut = new FizzBuzz()  
  
        expect:  
        sut.fizzBuzz(num) == result  
  
        where:  
        num || result  
        1 || "1"  
        3 || "Fizz"  
        5 || "Buzz"  
        15 || "FizzBuzz"  
  }  
}

書き方としては、setupでインスタンスやMockを作成し、expectで処理を実行する処理を書きます。
whereでexpectに渡すデータを定義することで、定義したパターンのテストを繰り返し行うことができます。

とても見やすくなりました。他にも良いフレームワークなどがあれば知りたい気持ちです。今後も美しいテストを意識していきたいと思います。

Previous
Next Post »

人気の投稿