当我通过SBT在Jenkins中运行我的Specs2测试时,一旦测试失败,构建就会被标记为失败。由于Jenkins通常区分构建失败和测试失败,我想改变它。
我知道Jenkins的构建失败是通过调用SBT的退出代码检测到的,一旦至少一次测试失败,它就会返回1。
我有什么选择假设我想避免更改我的build.sbt
(或一般项目)只是为了解决这个不便?
不知何故,我认为应该可以将标准的sbt项目放入标准的Jenkins安装中并使其按预期工作。
答案 0 :(得分:5)
tl; dr 将testResultLogger
与自定义测试结果记录器一起使用,该记录器不会引发TestsFailedException
反过来设置非0
退出代码。
注意到我错过了“以避免更改build.sbt
的要求。您可以使用任何其他*.sbt
文件,例如exitcodezero.sbt
或{{1}使用自定义~/.sbt/0.13/default.sbt
。
事实证明,由于sbt 0.13.5 ,有一种方法可以产生这种行为 - 请参见Added setting 'testResultLogger' which allows customisation of test reporting testResultLogger
出生的地方。
testResultLogger
因为the implementation of TestResultLogger.SilentWhenNoTests中可能已经读到> help testResultLogger
Logs results after a test task completes.
的默认值:
testResultLogger
这意味着当执行测试时出现问题时,会抛出results.overall match {
case TestResult.Error | TestResult.Failed => throw new TestsFailedException
case TestResult.Passed =>
}
异常,然后按以下方式报告:
TestsFailedException
我的想法是无论执行测试的结果如何都禁用抛出异常。将以下内容添加到[error] Failed: Total 3, Failed 1, Errors 0, Passed 2
[error] Failed tests:
[error] HelloWorldSpec
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
并使退出代码始终为build.sbt
:
0
取消注释testResultLogger in (Test, test) := new TestResultLogger {
import sbt.Tests._
def run(log: Logger, results: Output, taskName: String): Unit = {
println("Exit code always 0...as you wish")
// uncomment to have the default behaviour back
// TestResultLogger.SilentWhenNoTests.run(log, results, taskName)
}
}
以恢复默认行为。
TestResultLogger.SilentWhenNoTests.run
答案 1 :(得分:1)
你可以在一个总是返回0的包装器脚本中运行运行测试的构建部分。(如果你在一次运行中运行编译和测试,你必须将它拆分,这样你就不会# 39;忽略构建错误)
答案 2 :(得分:0)
您可以执行基于Jacek Laskowski的解决方案(至少在sbt> = 1.2.8中):
testResultLogger in (Test, test) := TestResultLogger {
(log, results, taskName) =>
try {
(testResultLogger in (Test, test)).value.run(log, results, taskName)
} catch {
case _: TestsFailedException =>
println("Ignore TestsFailedException to get exit code 0")
}
}
如果您有多模块项目,则可以将其实现为插件:
object TestExitCodePlugin extends AutoPlugin {
override def requires = JvmPlugin
override def trigger = allRequirements
override def projectSettings: Seq[Def.Setting[_]] = Seq(
testResultLogger in(Test, test) := TestResultLogger {
(log, results, taskName) =>
try {
(testResultLogger in(Test, test)).value.run(log, results, taskName)
} catch {
case _: TestsFailedException =>
println("Ignore TestsFailedException to get exit code 0")
}
}
)
}