当单元测试失败时,Jenkins 成功(Rails)

Posted

技术标签:

【中文标题】当单元测试失败时,Jenkins 成功(Rails)【英文标题】:Jenkins succeed when unit test fails (Rails) 【发布时间】:2012-07-12 23:21:51 【问题描述】:

我刚刚开始使用 Jenkins,这是我迄今为止遇到的第一个问题。基本上,即使在某些测试中发生错误,我的詹金斯工作也总是成功。这是我在 shell 配置中运行的:

bundle install 
rake db:migrate:reset
rake test:units
rake spec:models

问题是 Jenkins 仅在失败的任务是最后一个任务时才报告失败。例如,如果我将“rake test:units”放在最后一个任务中,它会在出现问题时通知错误。使用此配置,我只会收到 rspec 测试的错误报告,但不会收到单元测试的错误报告。

有人想知道为什么我不只使用 rspec 或单元测试,我们目前正在迁移到 rspec,但这个问题仍然很痛苦。

这是 Jenkinsm 日志的一部分,您可以看到其中一个单元测试失败,但 jenkins 仍然成功完成。

314 tests, 1781 assertions, 1 failures, 0 errors, 0 skips
rake aborted!
Command failed with status (1): [/var/lib/jenkins/.rvm/rubies/ruby-1.9.3-p1...]

Tasks: TOP => test:units
(See full trace by running task with --trace)
Lot of rspec tests here....
Finished in 3.84 seconds
88 examples, 0 failures, 42 pending
Pushing HEAD to branch master of origin repository
Pushing HEAD to branch master at repo origin
Finished: SUCCESS

【问题讨论】:

【参考方案1】:

另一种解决方案是将您的第一行更改为以下内容:

#!/bin/bash -e

如果脚本中的任何命令返回错误,这会告诉您的脚本失败。

见:Automatic exit from bash shell script on error

【讨论】:

【参考方案2】:

Jenkins 通过将您键入到构建步骤框中的命令写入临时文件,然后使用/bin/sh -xe 运行脚本来执行这些命令。

通常这会产生预期的效果:命令按顺序执行(并打印),当命令失败时脚本立即中止,即以非零退出代码退出。

如果您没有发生这种情况,唯一的原因可能是您已覆盖此行为。您可以通过使用以下两个字符开始构建步骤的第一行来覆盖它:#!

例如,如果您的构建步骤如下所示:

#!/bin/bash
bundle install
rake db:migrate:reset
rake test:units
rake spec:models

那么这意味着 Jenkins 会将脚本写入一个临时文件,并使用/bin/bash 执行。当这样调用时,bash 将一个接一个地执行命令,而不关心它们是否成功。 bash 进程的退出代码将是脚本中最后一个命令的退出代码,并且会在脚本结束时被 Jenkins 看到。

因此,请注意构建步骤第一行的内容。如果你不知道 shell 是如何工作的,那么就不要打乱码,让 Jenkins 来决定脚本应该如何运行。

如果您需要对构建步骤的执行方式进行更多控制,您应该研究您使用的 shell 的手册页,以了解如何使其按照您想要的方式运行。詹金斯在这里没有太大的作用。它只是按照你想要的方式执行你想要的 shell。

【讨论】:

你确实是对的,我已经将“#!/bin/bash”作为第一行:) 如果您添加#!/bin/bash -x,您可以获得 Jenkins 在脚本输出中显示它正在运行的命令的部分。真的,这只是 Jenkins 的默认 -xe 不想要的 -e【参考方案3】:

Jenkins 只能看到最后一个命令运行的结果代码,所以它无法知道rake test:units 的结果是什么。

最简单的方法可能是将这些命令中的每个命令作为单独的 jenkins 构建步骤。

【讨论】:

这个答案是 100% 正确的,但我认为让人们认为每个命令作为单独的构建步骤是 Jenkins 的最佳实践并不是一个好主意。请参阅下面的答案。 为作业的每个可破坏部分设置一个子步骤并不是一个坏主意,只要清楚每个子步骤都是独立运行的。另一种选择是检查构建中每个子步骤的结果,并在需要时退出并出错。 此解决方案的一个缺点是,如果您要发布测试结果(例如使用 rspec JUnitFormatter + Jenkins JUnit 发布者),具有单独的脚本步骤,每个步骤都可能导致构建失败,这将使您的测试趋势图由于某些测试套件甚至没有运行,因此会出现奇怪的向上/向下跳跃。我认为@sti 在他的回答中有更好的解决方案。

以上是关于当单元测试失败时,Jenkins 成功(Rails)的主要内容,如果未能解决你的问题,请参考以下文章

Jenkins 中的单元测试失败

仅当上一步失败时如何在 Jenkins 中运行条件步骤

Spring Boot 应用程序本地构建通过,但由于测试在 Jenkins 中失败

使用Docker和Jenkins运行测试 - 测试结果

搭建持续集成单元测试平台(Jenkins+Ant+Java+Junit+SVN)

解决Jenkins发送测试报告中用例成功失败数量为空的问题