Documentation

You are viewing the documentation for the 2.6.x development release. The latest stable release series is 2.4.x.

§specs2 による機能テストの記述

Playには、機能テストを支援する、多くのクラスや便利なメソッドが用意されています。これらの大半は、play.api.test パッケージか Helpers オブジェクトに含まれています。

これらのメソッドやクラスは次のインポートによって追加できます。

import play.api.test._
import play.api.test.Helpers._

§FakeApplication

Play では頻繁に実行中の Application をコンテキストとして実行する必要がありますが、これはたいてい play.api.Play.current によって提供されます。

テスト用の環境を提供するために、Play は FakeApplication クラスを提供します。このクラスは、異なる Global オブジェクト、追加の設定、追加のプラグインによって構成されています。

val fakeApplicationWithGlobal = FakeApplication(withGlobal = Some(new GlobalSettings() {
  override def onStart(app: Application) { println("Hello world!") }
}))

§WithApplication

アプリケーションをサンプルに渡すには WithApplication を使用します。明示的な Application を渡すことができますが、便宜上デフォルトの FakeApplication が提供されます。

WithApplication は組み込みの Around ブロックなので、独自のデータ集合を提供するために上書きできます。

abstract class WithDbData extends WithApplication {
  override def around[T: AsResult](t: => T): Result = super.around {
    setupData()
    t
  }

  def setupData() {
    // setup data
  }
}

"Computer model" should {

  "be retrieved by id" in new WithDbData {
    // your test code
  }
  "be retrieved by email" in new WithDbData {
    // your test code
  }
}

§WithServer

時々、テストから実際の HTTP スタックをテストをしたい時があります。その場合、WithServer を用いてテストサーバーを開始することができます。

"test server logic" in new WithServer(app = fakeApplicationWithBrowser, port = testPort) {
  // The test payment gateway requires a callback to this server before it returns a result...
  val callbackURL = s"http://$myPublicAddress/callback"

  // await is from play.api.test.FutureAwaits
  val response = await(WS.url(testPaymentGatewayURL).withQueryString("callbackURL" -> callbackURL).get())

  response.status must equalTo(OK)
}

port 値は、サーバーが実行しているポート番号を含んでいます。デフォルトは 19001 ですが、ポートを WithServer に渡すか、システムプロパティ testserver.port を設定することにより変更できます。継続的統合サーバーに組み入れる際に便利なので、各ビルドごとにポートを動的に予約できます。

FakeApplication もまた、テストサーバーに渡すことができ、これは、カスタムルートの設定や WS 呼び出しのテストに便利です。

val appWithRoutes = FakeApplication(withRoutes = {
  case ("GET", "/") =>
    Action {
      Ok("ok")
    }
})

"test WS logic" in new WithServer(app = appWithRoutes, port = 3333) {
  await(WS.url("http://localhost:3333").get()).status must equalTo(OK)
}

§WithBrowser

もし、ブラウザを使用したアプリケーションのテストを行いたい場合は、Selenium WebDriver を使用できます。Play は WebDriver を開始し、WithBrowser を使って FluentLenium が提供する便利な API でラップします。WithServer のように、ポートや Application を変更でき、使用する web ブラウザを選択することもできます。

val fakeApplicationWithBrowser = FakeApplication(withRoutes = {
  case ("GET", "/") =>
    Action {
      Ok(
        """
          |<html>
          |<body>
          |  <div id="title">Hello Guest</div>
          |  <a href="/login">click me</a>
          |</body>
          |</html>
        """.stripMargin) as "text/html"
    }
  case ("GET", "/login") =>
    Action {
      Ok(
        """
          |<html>
          |<body>
          |  <div id="title">Hello Coco</div>
          |</body>
          |</html>
        """.stripMargin) as "text/html"
    }
})

"run in a browser" in new WithBrowser(webDriver = WebDriverFactory(HTMLUNIT), app = fakeApplicationWithBrowser) {
  browser.goTo("/")

  // Check the page
  browser.$("#title").getTexts().get(0) must equalTo("Hello Guest")

  browser.$("a").click()

  browser.url must equalTo("/login")
  browser.$("#title").getTexts().get(0) must equalTo("Hello Coco")
}

§PlaySpecification

PlaySpecificationSpecification の拡張で、デフォルトの spec2 で提供された、Play のヘルパーメソッドと競合するいくつかのミックスインは含まれていません。Play のテストヘルパーと型は便宜上ミックスインしています。

object ExamplePlaySpecificationSpec extends PlaySpecification {
  "The specification" should {

    "have access to HeaderNames" in {
      USER_AGENT must be_===("User-Agent")
    }

    "have access to Status" in {
      OK must be_===(200)
    }
  }
}

§ビューテンプレートのテスト

テンプレートは標準的な Scala の機能なので、テストから実行でき、そして結果を確認できます。

"render index template" in new WithApplication {
  val html = views.html.index("Coco")

  contentAsString(html) must contain("Hello Coco")
}

§コントローラーのテスト

FakeRequest の提供による、いずれの Action コードも呼び出すことができます。

"respond to the index Action" in {
  val result = controllers.Application.index()(FakeRequest())

  status(result) must equalTo(OK)
  contentType(result) must beSome("text/plain")
  contentAsString(result) must contain("Hello Bob")
}

技術的に、ここで WithApplication は不要ですが、それにより何かを損なうことはありません。

§ルーターのテスト

自分で Action を呼び出す代わりに、Router にそれをさせることができます。

"respond to the index Action" in new WithApplication(fakeApplication) {
  val Some(result) = route(FakeRequest(GET, "/Bob"))

  status(result) must equalTo(OK)
  contentType(result) must beSome("text/html")
  charset(result) must beSome("utf-8")
  contentAsString(result) must contain("Hello Bob")
}

§モデルのテスト

SQL データベースを使用する時、inMemoryDatabase を使用して H2 データベースのインメモリインスタンスでデータベース接続を置き換えることができます。

val appWithMemoryDatabase = FakeApplication(additionalConfiguration = inMemoryDatabase("test"))
"run an application" in new WithApplication(appWithMemoryDatabase) {

  val Some(macintosh) = Computer.findById(21)

  macintosh.name must equalTo("Macintosh")
  macintosh.introduced must beSome.which(_ must beEqualTo("1984-01-24"))
}

Next: Guice によるテスト


このドキュメントの翻訳は Play チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。