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

Jenkins succeed when unit test fails (Rails)

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

1
2
3
4
bundle install
rake db:migrate:reset
rake test:units
rake spec:models

问题是,詹金斯只在最后一个任务失败时才报告失败。例如,如果我把"rake test:units"放在最后一个任务中,它会在出现问题时通知错误。使用这个配置,我只会得到RSPEC测试的错误报告,而不会得到单元测试的错误报告。

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

这是来自Jenkinsm的日志的一部分,您可以看到其中一个单元测试失败了,但Jenkins仍然以成功结束。

1
2
3
4
5
6
7
8
9
10
11
12
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

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

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

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

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

1
2
3
4
5
#!/bin/bash
bundle install
rake db:migrate:reset
rake test:units
rake spec:models

这意味着Jenkins将把脚本写入一个临时文件,并用/bin/bash执行。当这样调用时,bash将逐个执行命令,而不关心命令是否成功。bash进程的退出代码将是脚本中最后一个命令的退出代码,当脚本结束时,Jenkins将看到该代码。

所以,要注意在构建步骤的第一行所做的工作。如果您不知道shell是如何工作的,那么就完全不要使用散列键,让Jenkins决定脚本应该如何运行。

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


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

1
#!/bin/bash -e

这将告诉脚本在脚本中的任何命令返回错误时失败。

请参见:出错时自动退出bash shell脚本


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

最简单的事情可能是将这些命令的每个命令作为单独的Jenkins构建步骤。