§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
PlaySpecification
は Specification
の拡張で、デフォルトの 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 チームによってメンテナンスされているものではありません。 間違いを見つけた場合、このページのソースコードを ここ で確認することができます。 ドキュメントガイドライン を読んで、お気軽にプルリクエストを送ってください。