并行执行测试
我注意到SBT正在并行运行我的specs2测试。这看起来不错,除了我的一个测试涉及从文件读取和写入并因此不可预测地失败,例如,见下文。并行执行测试
有什么比
- 更好的选择,设置所有的测试以串行运行,
- 使用每个测试单独的文件名和撕裂起伏?
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
}
}
除了上面写的关于sbt的内容,您必须知道specs2默认同时运行所有规格的示例。
您仍然可以声明,对于给定的规范,必须按顺序执行示例。要做到这一点,你只需添加sequential
您的规格的开头:测试的套房
class WriteAndReadSpec extends Specification{
val file = new File("testFiles/tmp.txt")
sequential
"WriteAndRead" should {
...
}
}
wiki linkPablo Fernandez在his answer中给出的很不错,虽然这个例子中有一个小错误可能会导致一次性错误(尽管作为一个维基,我可以修改它)。这是一个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"
)
}
感谢您指出这是一个项目/ Build.scala文件,并且一直在努力。必须在看到我的测试(运行serial:test)之前更改过滤器以使用'contains'而不是'startsWith'。不幸的是,我仍然得到不可预知的行为,所以我猜猜它仍然在平行运行。 – Pengin
固定的顺序可能会导致测试用例的相互依赖性和负担维护。我倾向于在不接触文件系统的情况下进行测试(不管是业务逻辑还是序列化代码),或者如果它不可避免(如测试与文件馈送的集成),那么将使用创建临时文件:
// Create temp file.
File temp = File.createTempFile("pattern", ".suffix");
// Delete temp file when program exits.
temp.deleteOnExit();
其他答案解释了如何使用让他们顺序运行。
虽然他们是有效答案,但我认为最好是更改测试以让它们并行运行。(如果可能的话)
在你的例子中 - 为每个测试使用不同的文件。 如果你有数据库涉及 - 使用不同的(或随机)用户(或任何隔离,你可以) 等...
这是拼图的缺失部分。事实上,即使没有自定义Build.scala建议的其他答案,它也可以工作。我猜SBT并行性是跨越单独的测试文件而不是单个文件。 – Pengin
是的,sbt在测试之间控制这个,sequential是在测试用例中正确使用的。保持接近测试规格更有意义,因为那样会隐含记录。 –