超適当訳写経 『Groovy - Unit Testing』(Groovy公式ドキュメント) #junitbook
『GroovyからJUnitを扱う』ための前練習的な取り組みとして、Groovy公式ドキュメントから関連するページを写経してみよう、というエントリ。まずは更にそれら前段階として『Groovyでのユニットテスト』ページから超適当訳で実践メモを残してみる。超適当訳と自分の実践メモやら感想やら入り混じるので精度としてはかなり不安な気もしますが、その辺御容赦を。m(_ _)m 御指摘・修正等あれば速やかに対応したいと思います。
Groovyの利点
GroovyはJUnitテスティングを幾つかの方法でより、シンプルに、より"Groovy"にします。
- JUnitはGroovyのランタイムに組み込まれているため、Groovyシンタックスを使っているGroovy及びJavaクラスに対してJUnitテストをスクリプト実行出来る。
- Groovy側で、JUnitのアサート文追加メソッドを提供している。
- GroovyのユニットテストはAnt/Mavenで簡単にスクリプト化出来る(?)。
- Groovy Mocksを提供している。
- Groovy - Groovy Mocks(※Groovy公式)
この辺も参照。
記述例
Groovyでユニットテストを書く場合、GroovyTestCaseを拡張したクラスを作成する必要がある。
import static org.junit.Assert.*; class MyTest extends GroovyTestCase { void testSomething() { assert 1 == 1 assert 2 + 2 == 4 : "We're in trouble, arithmetic is broken" } }
Groovyのテストアサーション
- GroovyTestCaseでは以下のテストアサートメソッドを追加で提供している。処理詳細はドキュメント参照。
- assertArrayEquals
- assertLength
- assertContains
- assertToString
- assertInspect
- assertScript
- shouldFail
詳細
IDEでのGroovyTestCaseの実行
- GroovyTestSuiteを使いましょう。とある。
Eclipse上でGroovyTestCaseを含むTestSuiteを実行
- TestSuiteのsuite()メソッドはテストを返す。
- suite()メソッド内ではGroovyTestSuiteを作成したり、TestSuiteを追加したり出来る。
- 詳細はコード参照。
- suiteクラス
package junitbook.sandbox; import static org.junit.Assert.*; import junit.framework.TestSuite; class MyTestSuite extends TestSuite { private static final String TEST_ROOT = "test/junitbook/sandbox/" public static TestSuite suite() throws Exception { TestSuite suite = new TestSuite(); GroovyTestSuite gsuite = new GroovyTestSuite(); suite.addTestSuite(StackTest.class) suite.addTestSuite(gsuite.compile(TEST_ROOT + "GroovyStackTest.groovy")) suite.addTestSuite(gsuite.compile(TEST_ROOT + "MyTest.groovy")) return suite; } }
- Suiteクラスに対する、テストクラス各種。内容は超適当ですのであしからず。
- StackTest.java
package junitbook.sandbox; import static org.junit.Assert.*; import groovy.util.GroovyTestCase; import org.junit.Test; public class StackTest extends GroovyTestCase { @Test public void test() { assertEquals(1, 1); } }
-
- GroovyStackTest.groovy
package junitbook.sandbox; import static org.junit.Assert.*; import static org.hamcrest.CoreMatchers.*; import org.junit.Test; class GroovyStackTest extends GroovyTestCase { @Test void testAdd() { Stack stack = new Stack(); assertThat(stack.add(10, 20), is(30)) } @Test void testAdd2() { Stack stack = new Stack(); assertThat(stack.add(3, 4), is(7)) } }
-
- MyTest.groovy
package junitbook.sandbox; import static org.junit.Assert.*; class MyTest extends GroovyTestCase { void testSomething() { assert 1 == 1 assert 2 + 2 == 4 : "We're in trouble, arithmetic is broken" } }
最初上手く実行出来なくて、パスとかの問題なのかな?と思いきやこういう事でした。GroovyTestSuite使う際はSuite対象となるクラスもGroovyTestCaseなりを拡張させとかないとダメなんですね。分かってみれば確かにそうですけど。
- クラス実行は繋がるがテストが無い(test not founds)と言われる。@Testで宣言してるんだけどな〜
- ん、これもしかしてGroovyTestCase拡張しないとだめ?→各クラス、GroovyTestCaseを拡張したら認識してくれた(それまでそこに気付かず延々空振ってた)
ただこれ、Javaのクラスも同じようにするのは何か違う気がする(写経対象のページでは『Java, Groovy混在で行けるぜ』とは書いてあるものの)ので、実際の利用シーンでは
という形を採った方が混乱は少なさそうだな、という感じです。
スクリプトファイルをユニットテストのように利用
こちらも公式ページのコードに倣い、試してみる。
package junitbook.sandbox import groovy.util.GroovyTestSuite import junit.framework.Test import junit.textui.TestRunner import org.codehaus.groovy.runtime.ScriptTestAdapter class AllTests { static Test suite() { def allTests = new GroovyTestSuite(); def testRoot = "test/junitbook/sandbox/" allTests.addTest(new ScriptTestAdapter(allTests.compile(testRoot + "GroovySrciptOne.groovy"), [] as String[])) allTests.addTest(new ScriptTestAdapter(allTests.compile(testRoot + "GroovyScriptTwo.groovy"), [] as String[])) return allTests } } TestRunner.run(AllTests.suite())
実行に使ったGroovyスクリプト2つ。例によって中身は超適当。
- GroovyScriptOne.groovy
package junitbook.sandbox x = [1,2,3] assert x.size() == 3
- GroovyScriptTwo.groovy
package junitbook.sandbox assert "Hello,Groovy!".length() == 13
これはこれでJava/Groovyクラス同様、使うならSuiteクラスを分けて、という感じになりそうですね。
ページの残りは割愛。