2012-07-13 11 views
10

Apenas empiezo a usar Jenkins y este es el primer problema que he tenido hasta ahora. Básicamente, mi trabajo jenkins siempre tiene éxito incluso cuando se produce un error en algunas de las pruebas. Esto es lo que estoy corriendo en la configuración de la shell:Jenkins tiene éxito cuando la prueba de la unidad falla (Rails)

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

cosa es que Jenkins sólo informa de un fallo cuando la tarea que no es el último. Por ejemplo, si pongo "rake test: units" la última tarea notificará un error si algo sale mal. Al usar esta configuración, solo recibo informes de errores para las pruebas rspec pero no para las pruebas unitarias.

Cualquiera que se pregunte por qué no solo uso rspec o prueba de unidad, actualmente estamos migrando a rspec, pero este problema aún es doloroso.

Esto es parte del registro de Jenkinsm, ya que puede ver que una de las pruebas de la unidad falla pero los jenkins aún terminan con éxito.

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 

Respuesta

18

Jenkins ejecuta los comandos que escriba en un cuadro de Paso de construcción escribiéndolos en un archivo temporal y luego ejecutando el script usando /bin/sh -xe.

Normalmente, esto produce el efecto deseado: los comandos se ejecutan en secuencia (y se imprimen) y la secuencia de comandos se cancela inmediatamente cuando falla un comando, es decir, sale con un código de salida distinto de cero.

Si esto no te sucede, la única razón puede ser que hayas reemplazado este comportamiento. Puede anularlo iniciando la primera línea de su Paso de compilación con estos dos caracteres: #!.

Por ejemplo, si su Construir Paso ve así:

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

entonces significa Jenkins escribirá el guión a un archivo temporal y se ejecutará con /bin/bash. Cuando se invoca así, bash ejecutará comandos uno a uno y no les importa si tienen éxito. El código de salida del proceso bash será el código de salida del último comando en el script y Jenkins lo verá cuando finalice el script.

Por lo tanto, tenga cuidado con lo que pone en la primera línea del paso de compilación. Si no sabes cómo funciona Shell, no pongas un hash-bang y deja que Jenkins decida cómo se debe ejecutar el script.

Si necesita más control sobre cómo se ejecuta Build Step, debe estudiar la página man del shell que usa para averiguar cómo hacerlo funcionar de la manera que desee. Jenkins no tiene mucho papel aquí. Simplemente ejecuta el shell que querías de la forma que querías.

+1

Tenías razón, he tenido "#!/Bin/bash" como la primera línea :) –

+1

si agregas '#!/Bin/bash -x' puedes obtener la parte donde Jenkins muestra el comando que es corriendo en la salida del script. Realmente es solo el '-e' que no quieres del' -xe' por defecto de Jenkins – ZombieDev

5

Jenkins sólo puede ver el código de resultado de la última instrucción ejecutada por lo que no tiene forma de saber cuál es el resultado de rake test:units es.

Lo más fácil es tener cada comando de esos comandos como un paso de construcción de jenkins separado.

+0

no sabía de eso, funciona ahora, thx! –

+0

Esta respuesta es 100% correcta, pero no creo que sea una buena idea hacer que las personas piensen que cada comando como un paso de construcción separado es la mejor práctica en Jenkins. Ver mi respuesta a continuación. – sti

+0

Tener un subpaso para cada parte rompible del trabajo no es una mala idea, siempre y cuando esté claro que cada subpaso se ejecuta de forma independiente. Otra opción es verificar el resultado de cada subpaso en la compilación y salir con error, si es necesario. – Gonen

5

Una solución alternativa es cambiar su primera línea a lo siguiente:

#!/bin/bash -e 

Esto le dice a la secuencia de comandos a un error si cualquiera de los comandos en el script devuelve un error.

Ver: Automatic exit from bash shell script on error

Cuestiones relacionadas