01.01.JUnit 3 と ScalaTest の始め方

もし、JUnit 3 のテストを Scala で記述し実行したいなら、ScalaTest の アサーションとマッチャーを使って、もっと簡潔なコードを書くことができるでしょう。

アサーションを使うには、 org.scalatest.junit.AssertionsForJUnit の TestCase をミックスインします。

import junit.framework.TestCase import org.scalatest.junit.AssertionsForJUnit import scala.collection.mutable.ListBuffer import junit.framework.Assert._ class ExampleSuite extends TestCase with AssertionsForJUnit { var sb: StringBuilder = _ var lb: ListBuffer[String] = _ override def setUp() { sb = new StringBuilder("ScalaTest は") lb = new ListBuffer[String] } def testEasy() { // JUnit スタイルのアサーションを使う sb.append("かんたん!") assertEquals("ScalaTest はかんたん!", sb.toString) assertTrue(lb.isEmpty) lb += "sweet" try { "verbose".charAt(-1) fail() } catch { case e: StringIndexOutOfBoundsException => // こうなるはず } } def testFun() { // ScalaTest のアサーションを使う sb.append("たのしい!") assert(sb.toString === "ScalaTest はたのしい!") assert(lb.isEmpty) lb += "sweeter" intercept[StringIndexOutOfBoundsException] { "concise".charAt(-1) } } }

注意:

JUnit はアサーションから発生している例外を失敗(failure)と呼び、予期しない例外(エラー: error)と区別します。

org.scalatest.junit.AssertionsForJUnitをミックスインし、JUnit が ScalaTest のアサーションの失敗を「失敗」としてリポートするように(「エラー」として扱わないように)してください。

testEasy で使用される JUnit のアサーションと、testFun で使用される ScalaTest アサーションの簡潔さの違いが見てとれます。 Scala コンパイラでこのクラスをコンパイルすると、JUnit は作成されたクラスファイルを適切に実行します。 コンパイルするには、以下のように入力します。

scalac -cp scalatest-1.5.jar:junit-4.4.jar ExampleSuite.scala

JUnit を使ってテストを実行するには、いくつか方法がありますが、たとえば以下のように入力します。

$ scala -cp .:scalatest-1.5.jar:junit-4.4.jar junit.textui.TestRunner ExampleSuite .. Time: 0.032 OK (2 tests)

もし、JUnit でテストを実行するか、ScalaTest で実行するかを選択したいなら、org.scalatest.junit.JUnit3Suite をミックスインするといいでしょう。 JUnit3Suite は既に junit.framework の TestCase と AssertionsForJUnit をミックスインしているので、これらのトレイトは必要ありません。

import org.scalatest.junit.JUnit3Suite import scala.collection.mutable.ListBuffer import junit.framework.Assert._ class ExampleSuite extends JUnit3Suite { var sb: StringBuilder = _ var lb: ListBuffer[String] = _ override def setUp() { sb = new StringBuilder("ScalaTest は") lb = new ListBuffer[String] } def testEasy() { // JUnit スタイルのアサーションを使う sb.append("かんたん!") assertEquals("ScalaTest はかんたん!", sb.toString) assertTrue(lb.isEmpty) lb += "sweet" try { "verbose".charAt(-1) fail() } catch { case e: StringIndexOutOfBoundsException => // こうなるはず } } def testFun() { // ScalaTest のアサーションを使う sb.append("たのしい!") assert(sb.toString === "ScalaTest はたのしい!") assert(lb.isEmpty) lb += "sweeter" intercept[StringIndexOutOfBoundsException] { "concise".charAt(-1) } } }

ExampleSuite は JUnit の TestCase なので、JUnit から実行できます。

$ scala -cp .:scalatest-1.5.jar:junit-4.4.jar junit.textui.TestRunner ExampleSuite .. Time: 0.032 OK (2 tests)

しかし、ExampleSuite は ScalaTest の Suite でもあるので、ScalaTest からも実行できます。

$ scala -cp scalatest-1.5.jar:junit-4.4.jar org.scalatest.tools.Runner -p . -o -s ExampleSuite Run starting. Expected test count is: 2 ExampleSuite: - testFun(ExampleSuite) - testEasy(ExampleSuite) Run completed in 189 milliseconds. Total number of tests run: 2 Suites: completed 1, aborted 0 Tests: succeeded 2, failed 0, ignored 0, pending 0 All tests passed.

最後に、ScalaTest のマッチャーDSL を紹介します。 単純に ShouldMatchersForJUnit をミックスインしてください("should" より "must" の方が好き、という場合は MustMatchersForJUnit をミックスインしてください)。

import org.scalatest.junit.JUnit3Suite import org.scalatest.junit.ShouldMatchersForJUnit import scala.collection.mutable.ListBuffer import junit.framework.Assert._ class ExampleSuite extends JUnit3Suite with ShouldMatchersForJUnit { var sb: StringBuilder = _ var lb: ListBuffer[String] = _ override def setUp() { sb = new StringBuilder("ScalaTest は") lb = new ListBuffer[String] } def testEasy() { // ここでは、ScalaTest のアサーションを使う sb.append("かんたん!") assert(sb.toString === "ScalaTest はかんたん!") assert(lb.isEmpty) lb += "sweet" intercept[StringIndexOutOfBoundsException] { "concise".charAt(-1) } } def testFun() { // ScalaTest の should マッチャーを使う sb.append("たのしい!") sb.toString should be ("ScalaTest はたのしい!") lb should be ('empty) lb += "sweeter" evaluating { "clear".charAt(-1) } should produce [StringIndexOutOfBoundsException] } }

前の例と同じく、このケースも JUnit 、ScalaTest 双方からテストを実行できます。

$ scala -cp .:scalatest-1.5.jar:junit-4.4.jar junit.textui.TestRunner ExampleSuite .. Time: 0.082 OK (2 tests)

$ scala -cp scalatest-1.5.jar:junit-4.4.jar org.scalatest.tools.Runner -p . -o -s ExampleSuite Run starting. Expected test count is: 2 ExampleSuite: - testFun(ExampleSuite) - testEasy(ExampleSuite) Run completed in 116 milliseconds. Total number of tests run: 2 Suites: completed 1, aborted 0 Tests: succeeded 2, failed 0, ignored 0, pending 0 All tests passed.