02.TestNG と ScalaTest の始め方
もし、TestNG のテストを Scala で記述し実行したいなら、ScalaTest の アサーションとマッチャーを使って、もっと簡潔なコードを書くことができるでしょう。
アサーションを使うには、org.scalatest.Assertions をテストクラスにミックスインします。
import org.scalatest.Assertions
import scala.collection.mutable.ListBuffer
import org.testng.Assert._
import org.testng.annotations.Test
import org.testng.annotations.Configuration
class ExampleSuite extends Assertions {
var sb: StringBuilder = _
var lb: ListBuffer[String] = _
@Configuration { val beforeTestMethod = true }
def initialize() {
sb = new StringBuilder("ScalaTest は")
lb = new ListBuffer[String]
}
@Test def verifyEasy() { // TestNG-スタイルのアサーションを使う
sb.append("かんたん!")
assertEquals("ScalaTest はかんたん!", sb.toString)
assertTrue(lb.isEmpty)
lb += "sweet"
try {
"verbose".charAt(-1)
fail()
}
catch {
case e: StringIndexOutOfBoundsException => // こうなるはず
}
}
@Test def verifyFun() { // ScalaTest のアサーションを使う
sb.append("たのしい!")
assert(sb.toString === "ScalaTest はたのしい!")
assert(lb.isEmpty)
lb += "sweeter"
intercept[StringIndexOutOfBoundsException] {
"concise".charAt(-1)
}
}
}
verifyEasy で使用される TestNG のアサーションと、verifyFun で使用される ScalaTest アサーションの簡潔さの違いが見てとれます。
Scala コンパイラでこのクラスをコンパイルすると、TestNG は作成されたクラスファイルを適切に実行します。
コンパイルするには、以下のように入力します。
scalac -cp scalatest-1.5.jar:testng-5.7-jdk15.jar ExampleSuite.scala
TestNG を使ってテストを実行するには、いくつか方法がありますが、たとえば以下のように入力します。
$ scala -cp .:scalatest-1.5.jar:testng-5.7-jdk15.jar org.testng.TestNG -testclass ExampleSuite
[Parser] Running:
Command line suite
===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
もし、TestNG でテストを実行するか、ScalaTest で実行するかを選択したいなら、org.scalatest.testng.TestNGSuite をミックスインするといいでしょう。
トレイト TestNGSuite は既に Assertions をミックスインしているので、このトレイトは必要ありません。
import org.scalatest.testng.TestNGSuite
import scala.collection.mutable.ListBuffer
import org.testng.Assert._
import org.testng.annotations.Test
import org.testng.annotations.Configuration
class ExampleSuite extends TestNGSuite {
var sb: StringBuilder = _
var lb: ListBuffer[String] = _
@Configuration { val beforeTestMethod = true }
def initialize() {
sb = new StringBuilder("ScalaTest は")
lb = new ListBuffer[String]
}
@Test def verifyEasy() { // TestNG-スタイルのアサーションを使う
sb.append("かんたん!")
assertEquals("ScalaTest はかんたん!", sb.toString)
assertTrue(lb.isEmpty)
lb += "sweet"
try {
"verbose".charAt(-1)
fail()
}
catch {
case e: StringIndexOutOfBoundsException => // こうなるはず
}
}
@Test def verifyFun() { // ScalaTest のアサーションを使う
sb.append("たのしい!")
assert(sb.toString === "ScalaTest はたのしい!")
assert(lb.isEmpty)
lb += "sweeter"
intercept[StringIndexOutOfBoundsException] {
"concise".charAt(-1)
}
}
}
ExampleSuite は有効な TestNG のテストクラスなので、TestNG から実行できます。
$ scala -cp .:scalatest-1.5.jar:testng-5.7-jdk15.jar org.testng.TestNG -testclass ExampleSuite
[Parser] Running:
Command line suite
===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
しかし、ExampleSuite は ScalaTest の Suite でもあるので、ScalaTest からも実行できます。
$ scala -cp scalatest-1.5.jar:testng-5.7-jdk15.jar org.scalatest.tools.Runner -p . -o -s ExampleSuite
Run starting. Expected test count is: 2
ExampleSuite:
[Parser] Running:
Command line suite
- verifyEasy
- verifyFun
===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
Run completed in 315 milliseconds.
Total number of tests run: 2
Suites: completed 2, aborted 0
Tests: succeeded 2, failed 0, ignored 0, pending 0
All tests passed.
最後に、ScalaTest のマッチャーDSL を紹介します。
単純に ShouldMatchersForJUnit をミックスインしてください("should" より "must" の方が好き、という場合は MustMatchersForJUnit をミックスインしてください)。
import org.scalatest.testng.TestNGSuite
import org.scalatest.matchers.ShouldMatchers
import scala.collection.mutable.ListBuffer
import org.testng.Assert._
import org.testng.annotations.Test
import org.testng.annotations.Configuration
class ExampleSuite extends TestNGSuite with ShouldMatchers {
var sb: StringBuilder = _
var lb: ListBuffer[String] = _
@Configuration { val beforeTestMethod = true }
def initialize() {
sb = new StringBuilder("ScalaTest は")
lb = new ListBuffer[String]
}
@Test def verifyEasy() { // ScalaTest のアサーションを使う
sb.append("かんたん!")
assert(sb.toString === "ScalaTest はかんたん!")
assert(lb.isEmpty)
lb += "sweet"
intercept[StringIndexOutOfBoundsException] {
"concise".charAt(-1)
}
}
@Test def verifyFun() { // ScalaTest のマッチャーを使う
sb.append("たのしい!")
sb.toString should be ("ScalaTest はたのしい!")
lb should be ('empty)
lb += "sweet"
evaluating { "concise".charAt(-1) } should produce [StringIndexOutOfBoundsException]
}
}
前の例と同じく、このケースも TestNG 、ScalaTest 双方からテストを実行できます。
$ scala -cp .:scalatest-1.5.jar:testng-5.7-jdk15.jar org.testng.TestNG -testclass ExampleSuite
[Parser] Running:
Command line suite
===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
$ scala -cp scalatest-1.5.jar:testng-5.7-jdk15.jar org.scalatest.tools.Runner -p . -o -s ExampleSuite
Run starting. Expected test count is: 2
ExampleSuite:
[Parser] Running:
Command line suite
- verifyEasy
- verifyFun
===============================================
Command line suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
Run completed in 315 milliseconds.
Total number of tests run: 2
Suites: completed 2, aborted 0
Tests: succeeded 2, failed 0, ignored 0, pending 0
All tests passed.