如何设置SBT构建以在Jenkins的测试失败时返回零退出代码?

时间:2014-09-19 16:12:04

标签: jenkins sbt scalatest specs2

当我通过SBT在Jenkins中运行我的Specs2测试时,一旦测试失败,构建就会被标记为失败。由于Jenkins通常区分构建失败和测试失败,我想改变它。

我知道Jenkins的构建失败是通过调用SBT的退出代码检测到的,一旦至少一次测试失败,它就会返回1。

我有什么选择假设我想避免更改我的build.sbt(或一般项目)只是为了解决这个不便?

不知何故,我认为应该可以将标准的sbt项目放入标准的Jenkins安装中并使其按预期工作。

3 个答案:

答案 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")
        }
    }
  )
}