关于Scala:如何在sbt中的所有模块进行所有测试之前运行任务

How to run task before all tests from all modules in sbt

我有一个多模块游戏! 使用sbt构建的应用程序,并且在CI服务器上通过并行测试和演进存在问题:当sbt启动测试并首先启动演进脚本时,其他失败了一段时间,因为"数据库'default'处于不一致状态"(直到演进脚本停止) )。

我知道如何手动执行演进以及如何从sbt运行它们,但是我不知道如何将此配置插入sbt以确保仅一次应用演进,然后才对所有模块进行所有测试。

作为参考,我使用以下命令来运行演变:

1
2
3
4
5
6
object ApplyEvolutions extends App {
  OfflineEvolutions.applyScript(
    new File("."),
    this.getClass.getClassLoader,
    args.headOption.getOrElse("default"))
}

而我的sbt设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
val runEvolution = taskKey[Unit]("Applies evolutions")

lazy val runEvolutionTask = runEvolution := {
  val log = streams.value.log
  val dbName ="default"
  Run.executeTrapExit( {
    log.info(s"Applying evolutions for database $dbName")
    Run.run("controllers.ApplyEvolutions",
      (fullClasspath in Compile).value.map { _.data },
      Seq(dbName),
      log
    )(runner.value)
  }, log )
}

lazy val runEvolutionsBeforeTests = Seq(
  Tasks.runEvolutionTask,
  (test in Test) <<= (test in Test) dependsOn Tasks.runEvolution
)

tl; dr使用alias

我使用SBT 0.13.2-M3。

1
2
3
4
5
6
[task-dependson]> about
[info] This is sbt 0.13.2-M3
[info] The current project is {file:/Users/jacek/sandbox/so/task-dependsOn/}task-dependson 0.1-SNAPSHOT
[info] The current project is built against Scala 2.10.3
[info] Available Plugins: sbt.plugins.IvyModule, sbt.plugins.JvmModule, sbt.plugins.GlobalModule, com.typesafe.sbt.SbtGit, com.typesafe.sbt.SbtProguard, growl.GrowlingTests, org.sbtidea.SbtIdeaPlugin, sbtman.Plugin, np.Plugin, com.timushev.sbt.updates.UpdatesPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.3

这是一个任务示例-sayHelloT-在所有子项目中的test之前执行一次。 我使用Specs2作为测试框架。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.concurrent._

lazy val a = project

lazy val b = project

lazy val sayHelloT = taskKey[Unit]("Say Hello")

sayHelloT := {
  val log = streams.value.log
  log.info("Sleeping for 5 secs...")
  TimeUnit.SECONDS.sleep(5)
  log.info("Hello, my friend")
}

libraryDependencies in ThisBuild +="org.specs2" %%"specs2" %"2.3.10" %"test"

scalacOptions in Test ++= Seq("-Yrangepos")

addCommandAlias("sht",";sayHelloT; test")

如您所见,有两个子项目-ab-以及一个单独的别名sht,它将执行sayHelloT,并且仅在成功完成(需要5秒钟)后才会启动test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[task-dependson]> sht
[info] Sleeping for 5 secs...
[info] Hello, my friend
[success] Total time: 5 s, completed Mar 12, 2014 10:19:39 PM
[info] ASpec
[info]
[info] A project should
[info] + contain 11 characters
[info]
[info] Total for specification ASpec
[info] Finished in 205 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for task-dependson/test:test
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[info] BSpec
[info]
[info] B project should
[info] + contain 11 characters
[info]
[info] Total for specification BSpec
[info] Finished in 240 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 3 s, completed Mar 12, 2014 10:19:42 PM