FakeApplicationとFakeRequestを利用して、コントローラに対するテストを作成できます。testディレクトリにUserControllerSpec.scalaファイルを作成し、次のような内容でコントローラのテストを記述してみましょう。
import org.specs2.mutable._
import play.api.test._
import play.api.test.Helpers._
class UserControllerSpec extends Specification {
  "respond to the entryInit Action" in {
    running(FakeApplication()) {
      //ルーティング情報を使う
      val Some(result) = route(FakeRequest(GET, "/user/entry"))
      //コントローラを直接使う
      //val result = controllers.UserController.entryInit()(FakeRequest())
      status(result) must equalTo(OK)
      contentType(result) must beSome("text/html")
      charset(result) must beSome("utf-8")
      contentAsString(result) must contain("Entry user")
    }
  }
}
このテストでは、FakeApplicationで起動したアプリに対して、疑似的なリクエストを送ってコントローラの結果を取得しています。コントローラを直接呼んでもいいですし、route関数にルーティング情報を渡しても構いません。
contentAsStringにコントローラ呼び出し結果のresultを渡すと、レスポンスのhtml文字列を取得できます。ビューの内容を検証したい場合、この文字列をチェックしましょう。
必要があれば、テスト時にHTTPサーバを起動させることもできます。次のように記述することで、HTTPサーバが起動し、指定したURLにアクセスを行います。
・
・
  "run in a server" in new WithServer {
    await(WS.url("http://localhost:" + port).get).status must equalTo(OK)
  }
また、SeleniumのWebDriverを使用してブラウザのテストを行うこともできます。次のようにすれば、アプリ起動後に/user/entryへアクセスしてレスポンスのhtmlにある、<title>要素を検証しています。
・
・
  "run in a browser" in new WithBrowser {
    browser.goTo("/user/entry")
    browser.$("title").getText() must equalTo("entry user")
  }
}
さて、ここまでテストクラスの記述ができたら、playコンソールからtestを実行してみましょう。DBのテスト、コントローラのテスト、サーバ起動テスト、ブラウザのテストが実行されます。
[gyro] $ test ・ ・ [info] Passed: : Total 5, Failed 0, Errors 0, Passed 5, Skipped 0 [success] Total time: 25 s, completed 20xx/01/01 00:00:00
単体レベルのテストから機能テスト、ブラウザを使用したテストまで、簡単に記述して実行できました。今回はシンプルな検証しか行いませんでしたが、specs2自体は非常に高機能で、いろいろと便利な使い方ができるので、ドキュメントを確認してみてください。
今回はPlayアプリにおけるいろいろなテスト手法を紹介しました。DBのテストからWeb層のテストまで、いろいろなレイヤのテストをplayのテストの仕組みとspecs2で検証できることが分かったと思います。
最近の開発では、機能の実装とテストの作成がセットになっているので、テストの作成/実行が簡単なのは、非常にうれしいですね。
中村修太(なかむら しゅうた)
クラスメソッド勤務の新しもの好きプログラマです。昨年、東京から山口県に引っ越し、現在はノマドワーカーとして働いています。好きなJazzを聴きながらプログラミングするのが大好きです。
Copyright © ITmedia, Inc. All Rights Reserved.