如何在 sbt 中的测试任务之前附加自定义任务以执行?
Posted
技术标签:
【中文标题】如何在 sbt 中的测试任务之前附加自定义任务以执行?【英文标题】:How to attach custom task to execute before the test task in sbt? 【发布时间】:2012-01-23 05:01:07 【问题描述】:我正在将 SBT 与 Play 框架一起使用。
我创建了一个自定义 TaskKey
来在我的项目中运行 javascript 测试:
import sbt._
import sbt.Process._
import PlayProject._
object ApplicationBuild extends Build
val testJsTask = TaskKey[Unit]("testJs", "Run javascript tests.") :=
val main = PlayProject("xxx", 1.0, Seq())
.settings(defaultScalaSettings: _*)
.settings(testJsTask)
到目前为止一切顺利。
我想在有人执行test
任务时始终运行此testJsTask
。
我猜应该是这样的:
test in Test <<= (test in Test).dependsOn(testJsTask)
我不知道应该如何准确定义它。如何将依赖项添加到现有任务,如“测试”或“构建”?
更新
@Christian 提出更改后,构建定义如下所示:
object ApplicationBuild extends Build
val testJsTask = TaskKey[Unit]("testJs", "Run tests for javascript client.")
def testJs =
val main = PlayProject("xxx", 1.0, Seq())
.settings(defaultScalaSettings: _*)
.settings(testJsTask := testJs)
(test in Test) <<= (test in Test) dependsOn (testJs)
不幸的是,该解决方案也不起作用:
[error] /xxx/project/Build.scala:21: not found: value test
[error] (test in Test) <<= (test in Test) dependsOn (testJs)
[error] ^
[error] one error found
[error] file:/xxx/project/default-f468ae/compile:compile: Compilation failed
【问题讨论】:
你成功了吗?我最近的编辑对您有帮助吗? 不幸的是,我没有办法在 Play 版本上做同样的事情:/ 我会尝试做更多的测试,如果有任何成功,我会在这里报告。 我很想看看你是否找到了解决办法。 只为未来的读者:(test in Test) := (test in Test).dependsOn(otherTask).value
为我工作
【参考方案1】:
这是一种方法:
定义任务键:
val testJsTask = TaskKey[Unit]("testJs", "Run javascript tests.")
在您的项目设置中定义任务:
testJsTask <<= testJs
使测试依赖于它:
(test in Test) <<= (test in Test) dependsOn (testJs)
testJs 可以定义如下:
def testJs = (streams) map (s) =>
s.log.info("Executing task testJs")
// Your implementation
[编辑] 您必须在项目设置中定义任务依赖项。为了 一个“正常”的项目,你可以这样做:
lazy val testProject = Project(
"testProject",
file("testProject"),
settings = defaultSettings ++ Seq(
testJsTask <<= testJs,
(test in Test) <<= (test in Test) dependsOn (testJsTask)
)
)
【讨论】:
不知何故这对我来说看起来不完整。我想要做的是确保当有人运行“测试”命令时,除了所有其他测试之外,它还将执行 testJs。另外我看到你根本没有使用':='符号,我知道在构建任务时需要它 - 还是我错了?编辑:我看到了您的编辑,现在它开始变得更有意义了,我会立即尝试;) 你可以直接用:=定义一个任务。我更喜欢另一种可能性,因为这样我可以将任务键与实际任务分开。 我还是和以前一样的问题:Build.scala:19: not found: value test。 [错误](测试中的测试) 您能发布您当前的构建脚本吗? 我没用过play框架,但可能一个PlayProject没有(Test in Test)?【参考方案2】:Play 2.2.x 使用 SBT 0.13(请参阅What’s new in Play 2.2)。这带来了一些在 build.sbt
本身中编写任务的新方法(无需借助 project/
子目录中的 Scala 文件)。
如果您碰巧使用 Play 2.2.x,您可以在 build.sbt
中定义任务之间的依赖关系,如下所示:
lazy val testJsTask = taskKey[Unit]("Run JavaScript tests.")
testJsTask :=
println("Running JavaScript tests...")
java.util.concurrent.TimeUnit.SECONDS.sleep(3)
println("...done.")
test in Test :=
testJsTask.value
(test in Test).value
更多详情请参阅 SBT 官方文档中的Tasks。
【讨论】:
这是顺序运行任务还是同时运行? 依次。首先是 testJsTask,然后是测试任务。 据我了解这是不正确的@htomek scala-sbt.org/release/docs/… 使用Def.sequential()
按顺序运行任务scala-sbt.org/release/docs/Howto-Sequencing.html【参考方案3】:
对我来说,使用 dependsOn
语法不起作用。相反,我使用了测试的setup functionality 或sbt
。
您的示例将类似于以下内容:
val testJsTask = TaskKey[Unit]("testJs", "Run javascript tests.")
testJsTask :=
// ...whatever logic
// then inside your project settings
Test / testOptions += Tests.Setup(() => testJsTask.value)
请注意末尾的.value
。如果没有它,将是在不调用它的情况下引用函数。
【讨论】:
以上是关于如何在 sbt 中的测试任务之前附加自定义任务以执行?的主要内容,如果未能解决你的问题,请参考以下文章