質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.81%

unittestで強制終了( sys.exit() )をどのように表記すればよいのか分かりません。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,475

chapin

score 78

簡略して書きますと、整数の和を得る、というtashizan関数についてunittestを用いて書いています。

def tashizan(a,b):
    try:
        return int(a)+int(b)
    except ValueError:
        print("a,bは整数ではなく文字列の可能性があります")
        sys.exit(1)


関数を見る通り、引数にINTEGERではなく文字列が渡されたとき、スクリプトを止めたいためexcept ValueErrorで標準出力した後にsys.exit()でスクリプトを止めます。これをunittestで書いた場合以下のように書きました。関数の書き方及びunittestの書き方にアドバイスが有れば指摘してほしいです。現状ではFAILED (errors=1)になってしまいます。異常な引数を受け取ったらスクリプトを止める、かつ、unittestでFAILEDが表示されないことを目指しています。

import unittest , tashizan

class TestTashizan(unittest.TestCase):

    def test_tashizan_1(self):
        expected = 8
        actual = tashizan(2, 6)
        self.assertEqual(expected, actual)

    def test_tashizan_2(self):
        expected = 8
        actual = tashizan(6, "2")
        self.assertEqual(expected, actual)


    def test_tashizan_3(self):
        actual = tashizan("a", "6")
        self.assertRaises(ValueError)


if __name__ == "__main__":
    unittest.main(exit=False)


結果は以下のようになります。

..a,bは整数ではなく文字列の可能性があります
E
======================================================================
ERROR: test_tashizan_3 (__main__.TestTashizan)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\USER\Desktop\function.py", line 7, in tashizan
    return int(a) + int(b)
ValueError: invalid literal for int() with base 10: 'a'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "unit_test.py", line 21, in test_tashizan_3
    actual = tashizan("a", "6")
  File "C:\Users\USER\Desktop\function.py", line 10, in tashizan
    sys.exit(1)
SystemExit: 1

----------------------------------------------------------------------
Ran 3 tests in 0.001s

FAILED (errors=1)


なお関数のsys.exit()をコメントアウトするとFAILEDは表示されずうまくいくのですが、本来の目的であるスクリプトを止めるのが実現できなくなってしまいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

sys.exitは例外SystemExitを投げるので、それを監視してやれば良いです。
またassertRaisesの使い方も間違ってます。

手元の環境ではこれでテストが通りました。

def test_tashizan_3(self):
    with self.assertRaises(SystemExit):
        tashizan("a", "6")

あるいは

def test_tashizan_3(self):
    self.assertRaises(SystemExit, lambda: tashizan("a", "6"))

参考: unittest --- ユニットテストフレームワーク — Python 3.7.4 ドキュメント

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/09 00:41

    ありがとうございます!今日一日中調べてもうまく行かなかったので大変助かりました。
    本当にありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る