35 votes

S'engager dans git seulement si les tests sont réussis

J'ai récemment commencé à utiliser git, et a également commencé les tests unitaires (en utilisant Python unittest du module). Je voudrais que mes tests à chaque fois que j'ai commis, et n'engagent que si elles passent.

Je suppose que j'ai besoin d'utiliser pre-commit en /hooks, et j'ai réussi à le faire exécuter les tests, mais je n'arrive pas à trouver un moyen d'arrêter l'engager si elles échec des tests. Je suis en cours d'exécution de tests avec make test, qui à son tour est en cours d'exécution python3.1 foo.py --test. Il semble que je n'ai pas de sortie différents condition que les tests de réussite ou d'échec, mais je suis peut-être à la recherche dans le mauvais endroit.

Edit: Est-ce quelque chose de rare que je veux faire ici? J'aurais pensé que c'était une exigence commune...

Edit2: Juste au cas où les gens ne peuvent pas être pris la peine de lire les commentaires, le problème était qu' unittest.TextTestRunner n'a pas de sortie non nul, la possibilité que la suite de test est réussi ou pas. Pour l'attraper, j'ai fait:

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

31voto

Brian Campbell Points 101107

Je voudrais vérifier pour s'assurer que chaque étape de la voie, votre script renvoie un code de sortie non nulle en cas d'échec. Vérifier pour voir si votre python3.1 foo.py --test renvoie un code de sortie non nulle si un test échoue. Assurez-vous que votre make test commande renvoie un code de sortie non nulle. Et enfin, vérifiez que votre pre-commit crochet lui-même renvoie un code de sortie non nulle en cas d'échec.

Vous pouvez vérifier un code de sortie non nulle par l'ajout d' || echo $? à la fin d'une commande; ce qui vous permettra d'imprimer le code de sortie si la commande a échoué.

L'exemple suivant fonctionne pour moi (je suis rediriger stderr d' /dev/null pour éviter d'inclure trop de sortie superflues ici):

$ 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

Remarque l' || exit 1. Ce n'est pas nécessaire si l' make test est la dernière commande dans le crochet, comme le statut de sortie de la dernière commande sera le statut de sortie du script. Mais si vous avez plus tard vérifie dans votre pre-commit crochet, alors vous devez vous assurer que vous sortez avec une erreur; sinon, un bon de commande à la fin de l'hameçon sera la cause de votre script à la sortie avec un statut d' 0.

6voto

VonC Points 414372

Pourriez-vous analyser le résultat de l'python session de test et assurez-vous de sortir de votre pre-commit hook avec un état différent de zéro?

Le crochet doit sortir avec un état différent de zéro après l'émission d'un message approprié s' il veut arrêter le commettre.

Donc, si votre script python ne retourne pas le statut approprié pour une raison quelconque, vous devez déterminer ce statut directement à partir de l' pre-commit script hook.
Qui permettrait de s'engager à ne pas aller de l'avant si les tests échouent.
(ou vous pouvez appeler à partir du crochet un wrapper python qui appellent les tests, et d'assurer un sys.exit(exit_status) selon les résultats du test).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X