なんとな~くしあわせ?の日記

「そしてそれゆえ、知識そのものが力である」 (Nam et ipsa scientia potestas est.) 〜 フランシス・ベーコン

Play framework 2.x でユニットテストした

パッケージごとに機能を整理

org.specs2.mutable.Specification

・Spec2を使う、まあコピペのコピペなんすけど
・Spec2のユニットテスト自然言語っぽいDSL(?)で書ける

play.api.test.Helpers

・TestServer(3333)でほんとにテスト用のアプリケーションサーバが立ち上がってる
・browserと書くだけで擬似的なブラウザが起動してページのHTMLを読みとる
・Controller側だけではなくJavascriptやHTMLといったView側のテストケースが書けそう
・面倒な人手による試験を減らせそう
・コード修正によるViewのバグを防げそう*1

package test

import org.specs2.mutable._

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

/**
 * add your integration spec here.
 * An integration test will fire up a whole play application in a real (or headless) browser
 */
class IntegrationSpec extends Specification {

  "Application" should {

    "work from within a browser" in {
      running(TestServer(3333), HTMLUNIT) {
        browser =>
          browser.goTo("http://localhost:3333/")
          browser.pageSource must contain("P2P2ch is (probably) ready.")
      }
    }
  }
}

ハマリポイント

browserが動かない

[info] ! work from within a browser
[error]     ThrowableException: org/apache/http/config/Lookup (WebClient.java:1891)
[error] com.gargoylesoftware.htmlunit.WebClient.createWebConnection(WebClient.java:1891)
[error] com.gargoylesoftware.htmlunit.WebClient.<init>(WebClient.java:130)
[error] org.openqa.selenium.htmlunit.HtmlUnitDriver.newWebClient(HtmlUnitDriver.java:296)
[error] org.openqa.selenium.htmlunit.HtmlUnitDriver.createWebClient(HtmlUnitDriver.java:270)
[error] org.openqa.selenium.htmlunit.HtmlUnitDriver.<init>(HtmlUnitDriver.java:136)
[error] org.openqa.selenium.htmlunit.HtmlUnitDriver.<init>(HtmlUnitDriver.java:179)
[error] org.openqa.selenium.htmlunit.HtmlUnitDriver.<init>(HtmlUnitDriver.java:175)

依存関係になってるライブラリが足りないらしい、とりあえずいろいろ追加。

    "net.sourceforge.htmlunit" % "htmlunit" % "2.14" % "test",
    "org.apache.httpcomponents" % "httpclient" % "4.3.1" % "test",
    "org.apache.httpcomponents" % "httpcore" % "4.3.1" % "test"

Javascriptが無いとか怒られる

[error] c.g.h.h.HtmlPage - Error loading JavaScript from [http://localhost:3333/assets/javascripts/jquery-1.9.0.min.js].
java.io.IOException: Unable to download JavaScript from 'http://localhost:3333/assets/javascripts/jquery-1.9.0.min.js' (status 404).
	at com.gargoylesoftware.htmlunit.html.HtmlPage.loadJavaScriptFromUrl(HtmlPage.java:1124) ~[htmlunit-2.14.jar:2.14]
	at com.gargoylesoftware.htmlunit.html.HtmlPage.loadExternalJavaScriptFile(HtmlPage.java:1051) ~[htmlunit-2.14.jar:2.14]
	at com.gargoylesoftware.htmlunit.html.HtmlScript.executeScriptIfNeeded(HtmlScript.java:391) [htmlunit-2.14.jar:2.14]
	at com.gargoylesoftware.htmlunit.html.HtmlScript$3.execute(HtmlScript.java:266) [htmlunit-2.14.jar:2.14]
	at com.gargoylesoftware.htmlunit.html.HtmlScript.onAllChildrenAddedToPage(HtmlScript.java:286) [htmlunit-2.14.jar:2.14]
	at com.gargoylesoftware.htmlunit.html.HTMLParser$HtmlUnitDOMBuilder.endElement(HTMLParser.java:702) [htmlunit-2.14.jar:2.14]

自分の場合は、conf/routesがこうなっているので

GET /assets/*file controllers.Assets.at(path="/public", file)

とりあえず、以下のように空のファイルとか置いてやると黙った。
ワハハ、こいつ空のJavascriptとか読んで満足しとる。

// プロジェクトのルートで
$ mkdir -p public/javascripts/
$ touch public/javascripts/jquery-1.9.0.min.js

*1:コード修正 → Javascriptバグる → あっ!いっけねぇ!やっちまったッ!!しかし、ご安心ください、マネージャー!このユニットテストを潰せばすべて解決です!!