Фиксация в мерзавце, только если тесты передают

Я недавно начал использовать мерзавца и также начал поблочное тестирование (использующий 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)
35
задан Dan McGrath 8 February 2010 в 20:29
поделиться

2 ответа

Я бы проверил, чтобы убедиться, что на каждом шагу ваш сценарий возвращает ненулевой код выхода при отказе. Проверьте, чтобы убедиться, что ваш 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.

31
ответ дан 27 November 2019 в 15:41
поделиться

Не могли бы вы проанализировать результат тестового сеанса Python и обязательно выйти из вашего крючка предварительного коммитара с ненулевым статусом?

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

Итак, если ваш сценарий Python не возвращает соответствующую статус по какой-либо причине, вам необходимо определить этот статус непосредственно из Pre-Commit .
Это обеспечило бы, чтобы коммит не продвинулся, если тесты не удались.
(Или вы могли бы позвонить с крючка Python Wrapper, которая позвонила бы тестам и обеспечивает Sys.exit (Exit_Status) в соответствии с результатами теста).

6
ответ дан 27 November 2019 в 15:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: