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に渡すデータを定義することで、定義したパターンのテストを繰り返し行うことができます。
とても見やすくなりました。他にも良いフレームワークなどがあれば知りたい気持ちです。今後も美しいテストを意識していきたいと思います。
Sign up here with your email
ConversionConversion EmoticonEmoticon