単体テストで、メソッドがsys.exit()を呼び出すことをアサートすることは可能ですか?


98

私は時々呼び出すPython 2.7メソッドを持っています

sys.exit(1) 

適切な条件が満たされたときにこのコード行が呼び出されることを確認する単体テストを作成することは可能ですか?


回答:


155

はい。sys.exitレイズなSystemExitので、次のコマンドで確認できますassertRaises

with self.assertRaises(SystemExit):
    your_method()

のインスタンスにSystemExitは、code提案された終了ステータスに設定された属性があり、によって返されるコンテキストマネージャにassertRaisesは、キャッチされた例外インスタンスがexceptionとしてあるため、終了ステータスの確認は簡単です。

with self.assertRaises(SystemExit) as cm:
    your_method()

self.assertEqual(cm.exception.code, 1)

 

sys.exitドキュメント

Pythonを終了します。これは、SystemExit例外を発生させることによって実装されます...外部レベルでの終了試行を傍受することが可能です。


3
+1。ただし、呼び出しがsys.exit(1)(たとえば、ではなくsys.exit(0))であることを確認したい場合は、実際にそれcodeが1であることをアサートする必要がありassertRaisesRegexp(SystemExit, '1')ます。
abarnert 2013年

最初の引数の文字列表現で実行する正規表現パターンだけでなく、例外とその引数で実行unittestするために例外と呼び出し可能な述語を渡すことができるメソッドがあると確信していましたが、私はそうではありません。私が考えている他のテストモジュールはありますか?
abarnert 2013年

1
+1、エラーコードのチェックに関しては、次のことを行うのがはるかに簡単です: self.assertRaisesRegex( SystemExit, '^2$', testMethod ) コードが少なく、十分に読みやすい。
Marek Lewandowski、2015

1
@MarekLewandowski-タイプミス。する必要がありますself.assertRaisesRegexp
エフゲン2018

12

これが完全な動作例です。Pavelのすばらしい回答にもかかわらず、これを理解するのにしばらく時間がかかったので、役立つことを期待してここに含めます。

import unittest
from glf.logtype.grinder.mapping_reader import MapReader

INCOMPLETE_MAPPING_FILE="test/data/incomplete.http.mapping"

class TestMapReader(unittest.TestCase):

    def test_get_tx_names_incomplete_mapping_file(self):
        map_reader = MapReader()
        with self.assertRaises(SystemExit) as cm:
            tx_names = map_reader.get_tx_names(INCOMPLETE_MAPPING_FILE)
        self.assertEqual(cm.exception.code, 1)

3

あなたの質問に対する答えは、Pythonユニットテストのドキュメントで「例外のテスト」を検索して見つかりました。例を使用すると、単体テストは次のようになります。

self.assertRaises(SystemExit, your_function, argument 1, argument 2)

関数のテストに必要なすべての引数を含めることを忘れないでください。


1

Pavelの優れた答えに対する追加のメモとして、テストしている関数で特定のステータスが提供されているかどうかを確認することもできます。たとえばyour_method()、次のsys.exit("Error")ものが含まれている場合、「エラー」を具体的にテストすることが可能です。

with self.assertRaises(SystemExit) as cm:
    your_method()
    self.assertEqual(cm.exception, "Error")
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.