Я недавно начал использовать мерзавца и также начал поблочное тестирование (использующий Python unittest
модуль). Я хотел бы запустить свои тесты каждый раз, когда я фиксирую и только фиксирую, если они передают.
Я предполагаю, что должен использовать pre-commit
в /hooks
, и мне удалось заставить его запустить тесты, но я, может казаться, не нахожу способ остановить фиксацию, если они тестируют сбой. Я запускаю тесты с make test
, который в свою очередь работает python3.1 foo.py --test
. Кажется, что я не получаю другое условие выхода, могу ли тестовая передача или сбой, но я смотреть в неправильном месте.
Править: Это - что-то редкое, которое я хочу сделать здесь? Я думал бы, что это было общее требование...
Edit2: На всякий случай люди не могут быть побеспокоены для чтения комментариев, проблема была этим unittest.TextTestRunner
не выходит с ненулевым состоянием, успешен ли набор тестов или нет. Для ловли его я сделал:
result = runner.run(allTests)
if not result.wasSuccessful():
sys.exit(1)
Я бы проверил, чтобы убедиться, что на каждом шагу ваш сценарий возвращает ненулевой код выхода при отказе. Проверьте, чтобы убедиться, что ваш python3.1 foo.py --test
возвращает ненулевой код выхода при неудаче теста. Проверьте, не возвращает ли команда test
ненулевой код выхода. И, наконец, убедитесь, что ваш pre-commit
крючок сам возвращает ненулевой код выхода при неудаче.
Вы можете проверить ненулевой код выхода, добавив || 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
. В этом нет необходимости, если make test
является последней командой на крючке, так как статусом выхода последней команды будет статус выхода скрипта. Но если у вас есть более поздние проверки в вашем pre-commit
крючком, то вы должны убедиться, что вы выходите с ошибкой; в противном случае, успешная команда в конце крючка приведет к выходу вашего скрипта со статусом 0
.
Не могли бы вы проанализировать результат тестового сеанса Python и обязательно выйти из вашего крючка предварительного коммитара с ненулевым статусом?
Крюк должен выйти с ненулевым статусом после выдачи соответствующего сообщения, если Он хочет остановить коммит.
Итак, если ваш сценарий Python не возвращает соответствующую статус по какой-либо причине, вам необходимо определить этот статус непосредственно из Pre-Commit
.
Это обеспечило бы, чтобы коммит не продвинулся, если тесты не удались.
(Или вы могли бы позвонить с крючка Python Wrapper, которая позвонила бы тестам и обеспечивает Sys.exit (Exit_Status)
в соответствии с результатами теста).