39

私は最近 git を使い始め、単体テスト (Python のunittestモジュールを使用) も始めました。コミットするたびにテストを実行し、合格した場合にのみコミットしたいと思います。

pre-commitinを使用する必要があると推測/hooksし、テストを実行することはできましたが、テストが失敗した場合にコミットを停止する方法を見つけることができないようです。でテストを実行しています。make testこれは実行中python3.1 foo.py --testです。テストが成功したか失敗したかにかかわらず、別の終了条件が得られないように見えますが、間違った場所を探している可能性があります。

編集:これは私がここでやりたい珍しいことですか?私はそれが一般的な要件だと思っていたでしょう...

Edit2:人々がコメントを読むのが面倒な場合に備えて、問題はunittest.TextTestRunner、テスト スイートが成功したかどうかに関係なく、ゼロ以外のステータスで終了しないことでした。それをキャッチするために、私はしました:

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

3 に答える 3

33

途中の各ステップで、失敗時にスクリプトがゼロ以外の終了コードを返すことを確認します。python3.1 foo.py --testテストが失敗した場合にゼロ以外の終了コードが返されるかどうかを確認してください。make testコマンドがゼロ以外の終了コードを返すことを確認してください。最後に、pre-commit失敗時にフック自体がゼロ以外の終了コードを返すことを確認します。

|| echo $?コマンドの最後に追加することで、ゼロ以外の終了コードを確認できます。コマンドが失敗した場合、終了コードが出力されます。

次の例は私にとってはうまくいきます(/dev/nullここに余分な出力が含まれないようにstderrをリダイレクトしています):

$ 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 1make testがフックの最後のコマンドである場合、最後のコマンドの終了ステータスがスクリプトの終了ステータスになるため、これは必要ありません。ただし、後でフックをチェックする場合はpre-commit、エラーで終了することを確認する必要があります。そうしないと、フックの最後でコマンドが成功すると、スクリプトが のステータスで終了します0

于 2010-01-18T17:54:41.023 に答える
6

Could you parse the result of the python test session and make sure to exit your pre-commit hook with a non-zero status?

The hook should exit with non-zero status after issuing an appropriate message if it wants to stop the commit.

So if your python script does not return the appropriate status for any reason, you need to determine that status directly from the pre-commit hook script.
That would ensure the commit does not go forward if the tests failed.
(or you could call from the hook a python wrapper which would call the tests, and ensure a sys.exit(exit_status) according to the test results).

于 2010-01-18T15:52:46.313 に答える
0

手動で事前コミットを処理したくない場合の別のオプション: Python、Ruby などのテストと構文チェックを実行するための優れたツールがあります: github/overcommit

于 2015-05-19T09:18:13.467 に答える