2011-11-06 12 views
25

私は、SBTがspecs2テストを並行して実行していることに気付きました。これは、私のテストの1つがファイルからの読み書きを含んでいることを除き、予期せず失敗します。下記参照。テストの並列実行

は、各テストのために別のファイル名と涙ダウンを使用してシリアルで実行するすべてのテスト、

  • を設定

    1. よりも良くなるのオプションがありますか?
    class WriteAndReadSpec extends Specification{ 
        val file = new File("testFiles/tmp.txt") 
    
        "WriteAndRead" should { 
        "work once" in { 
         new FileWriter(file, false).append("Foo").close 
         Source.fromFile(file).getLines().toList(0) must_== "Foo" 
        } 
        "work twice" in { 
         new FileWriter(file, false).append("Bar").close 
         Source.fromFile(file).getLines().toList(0) must_== "Bar" 
        } 
        } 
    
        trait TearDown extends After { 
        def after = if(file.exists) file.delete 
        } 
    } 
    
  • 答えて

    35

    上記のsbtに加えて、specs2はデフォルトですべての仕様の例を同時に実行することを知っておく必要があります。

    指定された仕様では、例を順番に実行する必要があると宣言できます。これを行うには、単にあなたの仕様の先頭にsequentialを追加:スイートのテストの

    class WriteAndReadSpec extends Specification{ 
        val file = new File("testFiles/tmp.txt") 
    
        sequential 
    
        "WriteAndRead" should { 
        ... 
        } 
    } 
    
    +1

    これはパズルの欠けている部分でした。実際、カスタムBuild.scalaが他の答えによって示唆されていなくてもうまくいきました。 SBTの並列処理は、1つのファイル内ではなく、別々のテストファイルにまたがっていると思います。 – Pengin

    +0

    はい、sbtはテスト間でこれを制御します。シーケンシャルはテストケース内で使用するのに適しています。また、暗黙的に文書化されているため、テスト仕様に近づけておくほうが理にかなっています。 –

    2

    構成のシリアルテストをグループ化し、並行して残りを実行している間、それらを別々に実行されている第三の選択肢、があるようです。

    this wikiを確認し、「アプリケーションをパラレル実行する」を検索してください。

    +0

    リンクはもう動作しません。 –

    2

    his answerで与えられたはかなり良いですが、例えマイナスのエラーがありますが(wikiであり、それは修正できます)。実際にコンパイルして期待されるフィルタを生成するのはproject/Build.scalaですが、実際にテストで試してみませんでした。

    import sbt._ 
    import Keys._ 
    
    object B extends Build 
    { 
        lazy val root = 
        Project("root", file(".")) 
         .configs(Serial) 
         .settings(inConfig(Serial)(Defaults.testTasks) : _*) 
         .settings(
         libraryDependencies ++= specs, 
         testOptions in Test := Seq(Tests.Filter(parFilter)), 
         testOptions in Serial := Seq(Tests.Filter(serialFilter)) 
         ) 
         .settings(parallelExecution in Serial := false : _*) 
    
        def parFilter(name: String): Boolean = !(name startsWith "WriteAndReadSpec") 
        def serialFilter(name: String): Boolean = (name startsWith "WriteAndReadSpec") 
    
        lazy val Serial = config("serial") extend(Test) 
    
        lazy val specs = Seq(
         "org.specs2" %% "specs2" % "1.6.1", 
         "org.specs2" %% "specs2-scalaz-core" % "6.0.1" % "test" 
        ) 
    } 
    
    +0

    これはプロジェクト/ Build.scalaファイルだと思っていて、苦労していました。私のテスト(serial:testを実行しているとき)を見る前に、 'startsWith'の代わりに 'contains'を使うようにフィルタを変更しなければなりませんでした。残念ながら、まだ予測できない動作が起こっているので、それがまだ並行して実行されていると推測しています。 – Pengin

    3

    一定の順序がメンテナンス中のテストケースの相互依存性と負担につながることができます。

    私は(関係なくどちらかそれはビジネスロジックやシリアル化コードである)、またはそれが(ファイルとの統合をテストするためとしてフィード)避けられない場合は、一時ファイルを作成し使用するファイルシステムに触れることなくテストすることを好むだろう。

    // Create temp file. 
    File temp = File.createTempFile("pattern", ".suffix"); 
    // Delete temp file when program exits. 
    temp.deleteOnExit(); 
    
    0

    その他の回答は、それらを順番に実行する方法を説明しています。

    有効な回答ですが、私の意見では、は、テストを並行して実行できるように変更する方が良いです。(可能な場合)

    例では、テストごとに異なるファイルを使用します。 DBを使用している場合は、異なる(またはランダム)ユーザー(または何でも孤立するもの)を使用してください。 など...

    関連する問題