Scala入門記006 sbt + ScalaTest

プログラムを書いて何かしらのシステム開発するにはテストは必須だと思います。
プログラミング中に書くUnitTestの環境は現代の開発には欠かせないものでしょう。

今回はsbtによるScalaTtestとEclipse, IntelliJ IDEAでのテストスタイルについてまとめてみました。
Scala入門記の目次はこちらです。


テスト対象

テスト対象にするため、Scala入門記002 初めてのScalaプログラムで書いたHelloオブジェクトに挨拶文を作るためのメソッドを作りました。
1つ目の引数が存在する場合はその引数に応じて「Hello ほげほげ!」という挨拶文を生成します。
引数がない場合は「Hello!」という挨拶文を生成します。

object Hello {

  def main(args: Array[String]) {
    println(createGreeting(args))
  }

  def createGreeting(args: Array[String]) = {
    args.headOption match {
      case Some(name) => "Hello " + name + "!"
      case None => "Hello!"
    }
  }

}


これは、

sbt run

を実行すると

Hello!

を出力します。


また、引数を付けて

sbt "run Takashi"

を実行すると

Hello Takashi!

を出力します。


sbtの設定

ScalaTestを実行するにはScalaTestのライブラリに依存する必要があります。

build.sbt

libraryDependencies += "org.scalatest" % "scalatest_2.10" % "2.0" % "test"

を追記するとScalaTestがtest実行時のみ使えるようになります。


テストを書くときは

sbt ~test

とすると自動実行されて便利です。


テストコード

ScalaTestは色々なスタイルでテストコードを記述できるようです。
詳細はSelecting testing stylesを見ると紹介されています。

FlatSpec

まずはScalaSpecの公式サイトに習ってHelloSpecを作りました。

import org.scalatest._

class HelloSpec extends FlatSpec with Matchers {

  "Hello" should "create a simple greeting" in {
    val greeting = Hello.createGreeting(Array())
    greeting should be("Hello!")
  }

  it should "create a greeting with name" in {
    val greeting = Hello.createGreeting(Array("Takashi"))
    greeting should be("Hello Takashi!")
  }

}

FunSuite

import org.scalatest.FunSuite

class HelloSuite extends FunSuite {

  test("引数を指定しない場合に\"Hello!\"が取得できる") {
    val actual = Hello.createGreeting(Array())
    assert(actual == "Hello!")
  }

  test("引数に\"Takashi\"を指定した場合に\"Hello Takashi!\"が取得できる") {
    val actual = Hello.createGreeting(Array("Takashi"))
    assert(actual == "Hello Takashi!")
  }

}

今回は日本語も使ってみました。
macのターミナルでは正常に日本語が表示できました。

JUnit

build.sbt

libraryDependencies += "junit" % "junit" % "4.11" % "test"

を追加するとJUnitの形式も使えます。

import org.junit.Test
import org.scalatest.Assertions

class HelloTest extends Assertions {

  @Test def createGreetingWithEmptyArgs {
    val greeting = Hello.createGreeting(Array())
    assert(greeting == "Hello!")
  }

  @Test def createGreetingWithArgs {
    val greeting = Hello.createGreeting(Array("Takashi"))
    assert(greeting == "Hello Takashi!")
  }

}

残念なことにこのJUnitテストは

sbt test

では無視されてしまいます。

私は2番めのFunSuiteが好み&日本語もありかな、と思いました。


IDEでテスト

開発しながらテストするにはやっぱりIDEでテストしたいです。
今回はEclipseIntelliJ IDEAの両方でScalaTestの使い心地を試してみました。

Eclipseでテスト

EclipseにScalaTestのプラグインが入っているとEclipse内でテストができます。
ただし、現時点では緑のバーは見れなかったので残念でした。

f:id:t_hachinohe:20140116112305p:plain

IntelliJ IDEAでテスト

IntelliJ IDEAにScalaプラグインが入っているとIntelliJ IDEA内でテストができます。
こちらはEclipseと違い緑になってくれます。
やる気が出ますね!

f:id:t_hachinohe:20140116122115p:plain



まとめ

sbtでテストし続ける場合はIDE用とターミナル用に画面が2つ欲しくなりますね。
IDEでテストするにはIntelliJ IDEAを使うほうがモチベーションがあがりそうです。


Scala入門記の目次はこちらです。


今回の環境