Зафиксировать git только в случае прохождения тестов

Недавно я начал использовать git, а также начал модульное тестирование (используя unittest модуль Python). Я хотел бы запускать свои тесты каждый раз, когда я совершаю, и только совершать, если они пройдут.

Я предполагаю, что мне нужно использовать pre-commit in /hooks , и мне удалось заставить его запустить тесты, но я не могу найти способ остановить фиксацию, если тесты будут терпеть неудачу. Я запускаю тесты с make test , который, в свою очередь, запускает python3.1 foo.py --test . Похоже, что у меня нет другого условия выхода, проходят ли тесты или нет, но я могу искать не то место.

Редактировать: Это что-то необычное, что я хочу здесь сделать? Я бы подумал, что это обычное требование …

Edit2: На всякий случай люди не могут потрудиться, чтобы прочитать комментарии, проблема заключалась в том, что unittest.TextTestRunner не выходит с ненулевым статусом, независимо от того, успешно ли установлен тестовый пакет. Чтобы поймать это, я сделал:

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

3 Solutions collect form web for “Зафиксировать git только в случае прохождения тестов”

Я бы проверить, чтобы каждый шаг на пути, ваш скрипт возвращает ненулевой код выхода при ошибке. Убедитесь, что ваш python3.1 foo.py --test возвращает ненулевой код выхода, если тест python3.1 foo.py --test с ошибкой. Убедитесь, что команда make test возвращает ненулевой код выхода. И, наконец, убедитесь, что ваш pre-commit hook сам возвращает ненужный код выхода при ошибке.

Вы можете проверить ненужный код выхода, добавив || echo $? || echo $? до конца команды; который выдает код выхода, если команда не выполнена.

Следующий пример работает для меня (я перенаправляю stderr на /dev/null чтобы избежать включения слишком большого количества внешнего вывода):

 $ 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 

Обратите внимание на || exit 1 || exit 1 . Это необязательно, если make test является последней командой в hook, так как статус выхода последней команды будет статусом выхода скрипта. Но если у вас есть более поздние проверки в вашем pre-commit , вам необходимо убедиться, что вы выходите с ошибкой; в противном случае успешная команда в конце крючка заставит ваш скрипт выйти со статусом 0 .

Не могли бы вы проанализировать результат тестового сеанса python и убедиться, что вы покинули свой крюк pre-commit с ненулевым статусом?

Ключ должен выйти с ненулевым статусом после выдачи соответствующего сообщения, если он хочет остановить фиксацию.

Поэтому, если ваш скрипт python не возвращает соответствующий статус по какой-либо причине, вам нужно определить этот статус непосредственно из сценария крючка pre-commit .
Это гарантирует, что фиксация не будет идти вперед, если тесты не удались.
(или вы можете вызвать из крючка оболочку python, которая вызовет тесты, и обеспечить sys.exit(exit_status) соответствии с результатами теста).

Другой вариант, если вы не хотите обрабатывать вручную pre-commit: есть хороший инструмент для запуска тестов и синтаксических проверок для Python, Ruby и т. Д .: Github / overcommit

  • Создание события click в tkinter
  • Perfom python с помощью веб-интерфейса
  • Соответствующая иерархия файлов для unittesting в Python
  • Модульное тестирование для исключений в конструкторе Python
  • Ошибка при запуске теста django: время не замораживается с помощью freezegun
  • Тестирование модуля Argparse: подавить справочное сообщение
  • Предварительное тестирование Python для исключений при сбое покрытия
  • Могу ли я установить «random» с помощью unittest.mock.patch?
  • Python - лучший язык программирования в мире.