在下面的Build.scala文件的片段中,itTestWithService
任务在运行集成测试之前和之后启动测试服务器。
我想将此itTestWithService
任务附加到它:test键。但是如何?
lazy val mohs =
Project(id = "mohs", base = file("."))
.settings (
// I'd like the following but it creates a cycle that fails at runtime:
// test in IntegrationTest <<= testWithService
itTestWithService <<= testWithService
)
val itTestWithService = taskKey[Unit]("run integration test with background server")
/** run integration tests against a test server. (the server is started before the tests and stopped after the tests) */
lazy val testWithService = Def.task {
val log = streams.value.log
val launched = (start in testService).value
launched match {
case Success(_) =>
testAndStop.value
case Failure(e) =>
val stack = e.getStackTrace().mkString("\n")
log.error(s"failed to start test server: $e \n ${stack}")
}
}
/** run integration tests and then stop the test server */
lazy val testAndStop = Def.taskDyn {
val _ = (test in IntegrationTest).value
stop in testService
}
答案 0 :(得分:2)
在一个相关的github issue discussion中,Josh提出了一种解决我所询问的特定案例的方法(覆盖它:使用调用原始测试任务的任务进行测试)。
该方法通过重新实现测试任务来工作。我不知道是否有更通用的方式来访问任务的原始版本。 (更通用的方式是比这个更好的答案!)
以下是如何重新实现它:测试任务:
/** run integration tests (just like it:test does, but explicitly so we can overwrite the it:test key */
lazy val itTestTask: Initialize[Task[Unit]] = Def.taskDyn {
for {
results <- (executeTests in IntegrationTest)
} yield { Tests.showResults(streams.value.log, results, "test missing?") }
}
这是复合集成测试任务(从原始问题中略微演变,尽管该版本也应该起作用):
/** run integration tests against a test server. (the server is started before the tests and stopped after the tests) */
lazy val testWithServiceTask = Def.taskDyn {
(start in testService).value match {
case Success(_) =>
testAndStop
case Failure(e) =>
val stack = e.getStackTrace().mkString("\n")
streams.value.log.error(s"failed to start test server: $e \n ${stack}")
emptyTask
}
}
/** run integration tests and then stop the test server */
lazy val testAndStop = Def.taskDyn {
SbtUtil.sequence(itTestTask, stop in testService)
}
val emptyTask = Def.task {}
现在将我们构建的复合任务插入其中:测试键不会创建一个循环:
lazy val mohs =
Project(id = "mohs", base = file("."))
.settings (
test in IntegrationTest <<= testWithServiceTask,
)
答案 1 :(得分:1)
您可以在build.scala中添加自定义测试代码。这是我的一个项目的示例代码。请记住,您不必将其绑定到它:test。你可以任意命名。
lazy val AcceptanceTest = config("acc") extend(Test)
lazy val Kernel = Project(
id = "kernel",
base = file("."),
settings = defaultSettings ++ AkkaKernelPlugin.distSettings ++ Seq(
libraryDependencies ++= Dependencies.Kernel,
distJvmOptions in Dist := "-Xms256M -Xmx2048M",
outputDirectory in Dist := file("target/dist"),
distMainClass in Dist := "akka.kernel.Main system.SystemKernel"
)
).configs(AcceptanceTest)
.settings(inConfig(AcceptanceTest)(Defaults.testTasks): _*)
.settings(testOptions in AcceptanceTest := Seq(Tests.Argument("-n",
"AcceptanceTest"), Tests.Argument("-oD")))
请注意顶部的懒惰部分和.configs部分。
使用该设置,当我输入acc:test时,它会使用AcceptanceTestTag运行所有测试。您可以将服务器作为测试套件调用的一部分来启动。甚至可以通过需要服务器标记测试而不需要它,这样一旦你的套件变大并且运行时间更长,你就可以将它们分开。
编辑:已添加以回复评论。
要标记测试,请创建一个这样的标记
import org.scalatest.Tag
object AcceptanceTest extends Tag("AcceptanceTest")
然后把它放在你的测试中......
it("should allow any actor to subscribe to any channel", AcceptanceTest) {
这与上面相同的构建设置相同。当我调用acc:test。
时,只会运行带有That标签的测试您的问题让我想到的是我在同样情况下使用的解决方案。现在,你正在build.scala做的工作。我不确定你是否有可能在那里做你所说的......但我所做的却是同样的事情,但有点不同。我有一个特点,我混入所有需要流浪服务器的测试。我将使用它的测试标记为VagrantTest。
它就像一个单身人士。如果一个或多个测试需要它,它会启动。但它只能启动一个,所有测试都使用它。
你可以尝试做同样的事情,但要覆盖它:在配置文件中测试。而不是上面例子中的“acc”,而是“把它”。如果那不是你想要的,可能要看看是否还有其他人。
所以,基本上当我调用它时:测试它访问运行所有使用IntegrationTest测试标记的测试(以及那些使用VagrantTest和其他一些测试标记)。因此,所有运行时间较长的服务器测试都不会运行太多(耗时太长)。