超適当訳写経 『Groovy - Using JUnit 4 with Groovy』(Groovy公式ドキュメント) #junitbook

GroovyでJUnit4を使うには、というページの写経メモ。

簡単な例

  • まずはGroovyで。
package junitbook.sandbox.junit4;

import static org.junit.Assert.*;

import org.junit.Test;

class ArithmeticTest {
	
	@Test
	void additionIsWorking() {
		assertEquals 4, 2+2
	}

	@Test(expected=ArithmeticException)
	void divideByZero() {
		println 1/0
	}
}
  • また、shouldFailは以下のように書くことも出来る。
	final shouldFail = new GroovyTestCase().&shouldFail
	@Test
	void divideByZeroTest2(){
		shouldFail(ArithmeticException) {
			println 100/0
		}
	}

後半の例外が絡むテストは、例外が発生する事を期待するテスト。実行して問題無ければ何事も無くグリーンバーだが、エラーの場合は当然こうなる。

Hamcrestを使ったテスト

  • Hamcrest matchersを用いたJUnit4のテストも以下のように書く事が出来る。一番下のテスト等はGroovyらしい使い方も。
package junitbook.sandbox.junit4

import static org.junit.Assert.*
import static org.hamcrest.CoreMatchers.*
import static org.junit.matchers.JUnitMatchers.*

import org.junit.Test;

class LanguageTest {
	def languages = [tom:['Java', 'Groovy'], dick:['C#', 'Ruby']]
	
	@Test
	void tomKnowsJavaAndGroovyHamcrest() {
		assertThat languages['tom'], is(["Java","Groovy"])
		assertThat languages['tom'][0], containsString("v")
		assertThat languages['tom'][1], containsString("G")
	}

	@Test
	void tomKnowsJavaAndGroovyNative() {
		assert languages['tom'], is(["Java","Groovy"])
		assert languages['tom'].every {
			it.contains("v")
		}
	}

}

パラメータテスト

  • 以下の様なクラスをParameterizedを用いてテストすることも出来る。
class GroovyMultiplier {
    int triple(int val) {
        return val * 3
    }
}
  • テストコードはこんな感じ。
package junitbook.sandbox.junit4;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized)
class MultiplierTest {
	def testee
	def param
	def expectedResult
	
	@Parameters
	static data() {
		return (2..4).collect {
			[it, it * 3] as Integer[]
		}
	}
	
	MultiplierTest(a, b) {
		param = a
		expectedResult = b
		println "param:" + a + " expectResult:" + b
	}
	
	@Before
	void setUp() {
		testee = new GroovyMultiplier()
	}

	@Test
	void positivesFixed() {
		println "**test:positivesFixed"
		assert testee.triple(1) == 3: "+ve multiplier error"
	}
	
	@Test
	void positivesParameterized() {
		println "**test:positivesParameterized"
		assert testee.triple(param) == expectedResult
	}

	@Test
	void negativesParameterized() {
		println "**test:negativesParameterized"
		assert testee.triple(-param) == -expectedResult
	}

}
  • 実行結果。
param:2 expectResult:6
**test:positivesFixed
param:2 expectResult:6
**test:positivesParameterized
param:2 expectResult:6
**test:negativesParameterized
param:3 expectResult:9
**test:positivesFixed
param:3 expectResult:9
**test:positivesParameterized
param:3 expectResult:9
**test:negativesParameterized
param:4 expectResult:12
**test:positivesFixed
param:4 expectResult:12
**test:positivesParameterized
param:4 expectResult:12
**test:negativesParameterized

Theoryに関するテスト

JUnit4.4以降で使えるTheoryテストについても、以下のようにGroovyで利用する事が出来る。

package junitbook.sandbox.junit4;

import org.junit.runner.*
import org.junit.experimental.theories.*
import static org.junit.Assume.assumeTrue as assume

@RunWith(Theories)
class LanguageTheoryTest {
    @DataPoint public static String java = 'Java'
    @DataPoint public static String ruby = 'JRuby'
    @DataPoint public static String python = 'Jython'
    @DataPoint public static String javascript = 'Rhino'
    @DataPoint public static String groovy = 'Groovy'
    @DataPoint public static String scala = 'Scala'
    @DataPoint public static String csharp = 'C#'

    def jvmLanguages = [java, ruby, python, groovy, scala, javascript]

    def teamSkills = [
        tom:   [java, groovy, ruby],
        dick:  [csharp, scala, java, python],
        harry: [javascript, groovy, java]
    ]

    @Theory void everyone_knows_java() {
        teamSkills.each {person, skills ->
            assert java in skills
        }
    }

    @Theory void someone_knows_each_jvm_language(String language) {
        assume language in jvmLanguages
        assert teamSkills.any { person, skills ->
            language in skills
        }
    }

    @Theory void tom_knows_all_languages_ending_with_y(String language) {
        assume language.endsWith('y')
        assert language in teamSkills.tom
    }
}


まぁ、そんなにJavaと違和感無く扱え、要所でGroovyの良い所を使いつつより効率的なテストが書けるよ、という感じですかね。

JUnit実践入門』写経及び各所でのテストコード記述の際には、適所でうまいことGroovyを取り込めて行ければと思います。書籍写経はJava/Groovy双方で試してみたい。