2013-11-27 20 views
8

は、私にとっては許容できないほど遅いです。これは、新しいWithApplicationがすべての例でフレームワークを開始および停止しているためです。私が間違ってはいけない、フレームワーク自体が非常に高速に読み込まれますが、データベースが設定されていれば(驚き!)、状況はひどくなります。高速テスト実行

"The database layer" should { 

    "test1" in { 
    1 must be equalTo(1) 
    } 
    ... 
    "test20" in { 
    1 must be equalTo(1) 
    } 
} 

実行時間:2秒

は、ここではいくつかのmeasurmentsです。パフォーマンスの向上

短所:

すべての例でWithApplicationと同じテストを 9秒

を消費し、私はより良い結果にthis answer

import play.api.Play 
import play.api.test.FakeApplication 
import org.specs2.mutable.Specification 
import scalikejdbc._ 

class MySpec extends Specification { 

var fake: FakeApplication = _ 

step {fake = FakeApplication(...)} 
step {Play.start(fake)} 

"The database layer" should { 

    "some db test" in { 
    DB localTx { implicit session => 
     ... 
    } 
    } 

    "another db test" in { 
    DB localTx { implicit session => 
     ... 
    } 
    } 

    step {Play.stop()} 
} 

}

賛成論への感謝をachiveすることができました

  • コピー&ペーストする必要がありますセットアップとティアダウンコードを 私は「クラスMySpecはNoWasteOfTimeで 仕様に拡張する」のようなものを意味し、再利用することにより(それを再利用する方法を知らないので、

  • 新しいWithApplication() Helpers.runningはこの

synchronized { 
    try { 
    Play.start(fakeApp) 
    block 
    } finally { 
    Play.stop() 
    play.api.libs.ws.WS.resetClient() 
    } 
} 

のように見えた呼び出しますので、私は完全にHelpers.runningをエミュレートすることはできませんリフレクションなしで動作します(resetClientは自分のコードでは表示されません)。

私の問題をどのように達成するかについて、違反または別の方法を打ち破る方法を提案してください。

+0

仕様のためにセットアップ/ティアダウンを一度行いたいのですか、それともその中のすべてのテストでそれをやりたいのですか? –

+0

18か月後にPlayがまだこの動作を変更していないのは残念です。テストごとにアプリを起動するのはばかげている。 Play 3には実行中のアプリケーションの必要性をなくすためのDIがあります。 – andyczerwonka

答えて

9

それが最善の解決策である場合、私は知らないが、このスレッドで: Execute code before and after specification

あなたは再利用可能なコードのためのソリューションを読むことができます。少し修正して実装しました。私にとってbeforeAllステップは実行されず、sequential修飾子が追加されました。

import org.specs2.mutable._ 
import org.specs2.specification._ 

class PlayAppSpec extends Specification with BeforeAllAfterAll{ 
    sequential 
    lazy val app : FakeApplication = { 
     FakeApplication() 
    } 

    def beforeAll(){ 
     Play.start(app) 
    } 

    def afterAll(){ 
     Play.stop() 
    } 
} 
import org.specs2.specification.Step 

trait BeforeAllAfterAll extends Specification { 
    // see http://bit.ly/11I9kFM (specs2 User Guide) 
    override def map(fragments: =>Fragments) = { 
    beforeAll() 
    fragments^Step(afterAll) 
    } 


    def beforeAll() 
    def afterAll() 
} 

私はmapStep(...)^fragments^Step(...)と良いだろうと思うが、それは私のためbeforeAllを実行しませんでした。 「Global setup/teardown」のユーザーガイド(http://bit.ly/11I9kFM)には、怠惰なvalを使用するように指示されています。

全体的に、これを設定するのは苦痛でした。同じFakeApplication再利用する場合私の問題は Exception in thread "Thread-145" java.net.SocketException: Connection reset それとも

Configuration error[Cannot connect to database [default]] (Configuration.scala:559)

た: SQLException: Attempting to obtain a connection from a pool that has already been shutdown.

をブロック「に」私は、それは常にすべてのための新しいアプリケーションを作成するよりも、このようはるかに論理的だと思いますかすべてのテストを1つのブロックに追加します。

+0

私はあなたのアプローチを間違いなく好む、魅力のように動作します。 – Jeriho

関連する問題