Cometer en git solo si las pruebas pasan

Recientemente comencé a usar git y también comencé a realizar pruebas unitarias (usando el módulo de prueba de unidad de Python). Me gustaría realizar mis pruebas cada vez que me comprometo, y solo las hago si pasan.

Supongo que necesito usar pre-commit en /hooks , y he logrado hacer que ejecute las pruebas, pero parece que no puedo encontrar una manera de detener la confirmación si las pruebas fallan. Estoy ejecutando las pruebas con make test , que a su vez ejecuta python3.1 foo.py --test . Parece que no obtengo una condición de salida diferente si las pruebas pasan o no, pero puedo estar buscando en el lugar equivocado.

Edit: ¿Es esto algo raro que quiero hacer aquí? Pensé que era un requisito común …

Edit2: En caso de que no se pueda molestar a la gente para leer los comentarios, el problema fue que unittest.TextTestRunner no sale con un estado distinto de cero, ya sea que el conjunto de pruebas sea exitoso o no. Para atraparlo, hice:

 result = runner.run(allTests) if not result.wasSuccessful(): sys.exit(1) 

    Me aseguraría de asegurarse de que en cada paso del camino, su secuencia de comandos devuelva un código de salida distinto de cero en caso de error. Verifique si su python3.1 foo.py --test devuelve un código de salida distinto de cero si falla una prueba. Verifique para asegurarse de que su comando make test devuelve un código de salida distinto de cero. Y, por último, compruebe que su propio pre-commit devuelve un código de salida distinto de cero en caso de error.

    Puede verificar un código de salida distinto de cero agregando || echo $? || echo $? hasta el final de un comando; eso imprimirá el código de salida si el comando falla.

    El siguiente ejemplo funciona para mí (estoy redirigiendo stderr a /dev/null para evitar incluir demasiada salida extraña aquí):

     $ python3.1 test.py 2>/dev/null || echo $? 1 $ make test 2>/dev/null || echo $? python3.1 test.py 2 $ .git/hooks/pre-commit 2>/dev/null || echo $? python3.1 test.py 1 

    test.py :

     import unittest class TestFailure(unittest.TestCase): def testFail(self): assert(False) if __name__ == '__main__': unittest.main() 

    Makefile :

     test: python3.1 test.py 

    .git/hooks/pre-commit :

     #!/bin/sh make test || exit 1 

    Tenga en cuenta el || exit 1 || exit 1 . Esto no es necesario si make test es el último comando en el gancho, ya que el estado de salida del último comando será el estado de salida del script. Pero si tiene verificaciones posteriores en su pre-commit , entonces debe asegurarse de salir con un error; de lo contrario, un comando exitoso al final del enganche hará que su script salga con un estado de 0 .

    ¿Podría analizar el resultado de la sesión de prueba de python y asegurarse de salir de su gancho de confirmación previa con un estado distinto de cero?

    El gancho debe salir con un estado distinto de cero después de emitir un mensaje apropiado si desea detener la confirmación.

    Por lo tanto, si su secuencia de comandos de Python no devuelve el estado apropiado por alguna razón, debe determinar ese estado directamente desde la secuencia de comandos de enganche de pre-commit .
    Eso aseguraría que la confirmación no avance si las pruebas fallaban.
    (o puede llamar desde el gancho un envoltorio de python que llamaría a las pruebas y garantizar un sys.exit(exit_status) acuerdo con los resultados de la prueba).

    Otra opción, si no desea manejar los pre-commit manualmente: existe una buena herramienta para ejecutar pruebas y verificaciones de syntax para Python, Ruby, etc.: github / overcommit