0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python 3 エンジニア認定実践試験対策 (8) - unittest

Last updated at Posted at 2024-11-27

Pythonを数年使ってきて、改めて知識の整理と最新仕様のキャッチアップのために Python 3 エンジニア認定実践試験を受験しようと思い、私的に作成した資料から簡易版を作成しました。
最後に練習問題を設けましたので、解説を読んだら記憶定着のために練習問題へチャレンジしてください。最後に答えを掲載しています。


unittest

unittestとは

  • Pythonの標準ユニットテストフレームワーク
  • 複雑なテストケースを管理し実行できる。

テストランナー

  • 「テストランナー」がテスト実行と結果出力を管理する。
  • テストランナーは、ルールに従って作成されたテストクラス/テストメソッドを検索し実行する。

テストケースの作成

  • テストケースの作成ルール
    • unittest をインポート
    • テストクラスは unittest.TestCase を継承
    • テストメソッド名は test_ で始める
import unittest
from example import sum_function

class SumTest(unittest.TestCase):
    def test_sum_of_two_numbers(self):
        """ sum_function のテストコード """
        result = sum_function(1, 2)
        expected = 3
        self.assertEqual(result, expected)

if __name__ == '__main__':
    unittest.main()
  • テストケースの実行
    • コマンド: $ python test_sum.py

アサーションメソッド

  • テスト結果を確認するためのメソッド

  • 代表的なメソッド:

    • assertEqual(a, b): aとbが同一
    • assertNotEqual(a, b): aとbが異なる
    • assertTrue(x): xがTrue
    • assertFalse(x): xがFalse
    • assertIsNone(x): xがNone
    • assertRaises(exception): 指定した例外が発生
  • アサーションメソッドの使用例

    import unittest
    from example import sum_function
    
    class SumTest(unittest.TestCase):
        def test_assert_equal(self):
            result = sum_function(1, 2)
            expected = 3
            self.assertEqual(result, expected)
    
        def test_assert_is_not_none(self):
            result = sum_function(1, 2)
            self.assertIsNotNone(result)
    
        def test_assert_is_instance(self):
            result = sum_function(1, 2)
            self.assertIsInstance(result, int)
    
        def test_assert_raises(self):
            with self.assertRaises(TypeError):
                sum_function(None, 2)
    
    if __name__ == '__main__':
        unittest.main()
    

テスト結果の注意点

  • unittestでは、成功したアサーションの詳細は表示されない。
  • テスト結果は、結果の簡潔さを重視して失敗やエラー情報だけを表示する。
  • ただし、テストが成功した場合、「.」を表示する。
  • 成功したテストの詳細を確認する場合、ログやprint文を使用する。

複数アサーションの実行とエラー処理 — subTest()メソッドとwith文

  • 1つのテストメソッドに複数のアサーションメソッドがある場合、エラーになった時点で以降のアサーションメソッドが実行されないことがある。
  • subTest()with文を使って複数アサーションを1つのテストメソッド内で実行可能。
import unittest
from example import sum_function

class SumTest(unittest.TestCase):
    def test_sum_of_two_numbers(self):
        test_cases = [
            [2, 5, 7],
            [4, 1, 6],  # エラーケース
            [7, 2, 9],
        ]
        
        for idx, case in enumerate(test_cases):
            x, y, expected_result = case
            with self.subTest(f'{x} + {y} = {expected_result}', idx=idx):
                self.assertEqual(sum_function(x, y), expected_result)

if __name__ == '__main__':
    unittest.main()

テストの前処理 — setUp(), setUpClass()

テストの前処理とは、setUp()メソッドとsetUpClass()メソッドはテスト実行前に自動実行されます。データベースへのテストデータの投入などの準備作業によく使われます。

  • setUp()

    • テストメソッド実行前に呼び出されるメソッド。
    • 各テストメソッドの実行前に1回ずつ自動で呼ばれる。
  • setUpClass()

    • クラス内のテストが実行される前に1回だけ呼び出されるクラスメソッド。
    • @classmethodでデコレートし、cls (クラス)を引数に取る必要があります。
    import unittest
    
    class SampleTest(unittest.TestCase):
        def setUp(self):
            print('setUp 実行')
    
        @classmethod
        def setUpClass(cls):
            print('setUpClass 実行')
    
        def test_case1(self):
            print('test_case1 実行')
    
        def test_case2(self):
            print('test_case2 実行')
    
    if __name__ == '__main__':
        unittest.main()
    

テストの後処理 — tearDown(), tearDownClass()

テストが実行された後に、必要なクリーンアップ処理を行うために使用します。

  • tearDown()

    • テストメソッド実行後に呼び出される。
    • テストの結果にかかわらず、setUp()が成功した場合にのみ呼ばれる。
  • tearDownClass()

    • クラス内のテストが実行された後に1回だけ呼び出されるクラスメソッド。
    import unittest
    
    class SampleTearDownTest(unittest.TestCase):
        def tearDown(self):
            print('tearDown 実行')
    
        @classmethod
        def tearDownClass(cls):
            print('tearDownClass 実行')
    
        def test_case1(self):
            print('test_case1 実行')
    
        def test_case2(self):
            print('test_case2 実行')
    
    if __name__ == '__main__':
        unittest.main()
    

コマンドラインでテストを実行する

  • 特定モジュール単位のテスト実行:

    $ python -m unittest test_module1 test_module2
    
  • クラス単位のテスト実行:

    $ python -m unittest test_module.TestClass
    
  • メソッド単位のテスト実行:

    $ python -m unittest test_module.TestClass.test_method
    
  • コマンドラインオプション

    • -b, --buffer: 標準出力とエラーをバッファリングし、最後にまとめて表示。
    • -c, --catch: 複数テスト実行中にCtrl + Cが押されても即中断せず、その時に実行中のテストが終わるところまで中断を遅延させる。(実行予定だったテストは実行されない。)
    • -f, --failfast: 初回のエラーでテストを停止。
    • -k: パターンにマッチするテストのみ実行。複数条件を指定できる -k 条件1 -k 条件2。
    • --locals: トレースバックに局所変数も表示(通常、局所変数は表示されない。)

確認問題

  1. unittestとは何ですか?
    a) Pythonの標準ライブラリ
    b) Pythonの標準ユニットテストフレームワーク
    c) Pythonのデバッグツール
    d) Pythonのパッケージ管理ツール

  2. テストランナーの役割は何ですか?
    a) テストケースを作成する
    b) テストの実行と結果出力を管理する
    c) テストのエラーを修正する
    d) テストのパフォーマンスを測定する

  3. テストメソッド名はどのように命名する必要がありますか?
    a) testMethod
    b) testMethodName
    c) test_で始める
    d) testMethod_

  4. assertEqual(a, b)の役割は何ですか?
    a) aとbが異なることを確認する
    b) aとbが同一であることを確認する
    c) aがTrueであることを確認する
    d) aがNoneでないことを確認する

  5. setUp()メソッドはいつ呼び出されますか?
    a) テストクラスの初期化時
    b) 各テストメソッドの実行前
    c) テストメソッドの実行後
    d) テストクラスの実行後

  6. tearDown()メソッドの目的は何ですか?
    a) テストの前処理を行う
    b) テストの後処理を行う
    c) テストの結果を表示する
    d) テストの実行を中断する

  7. setUpClass()メソッドはどのようにデコレートされますか?
    a) @staticmethod
    b) @classmethod
    c) @unittest
    d) @setup

  8. subTest()メソッドの使用目的は何ですか?
    a) 複数のテストを一度に実行する
    b) 複数のアサーションを1つのテストメソッド内で実行する
    c) テストの結果をログに記録する
    d) テストの実行をスキップする

  9. テスト結果が成功した場合、unittestは何を表示しますか?
    a) 成功したテストの詳細
    b) エラー情報
    c) "."(ドット)
    d) "Success"

  10. コマンドラインで特定のテストメソッドを実行するためのコマンドはどれですか?
    a) $ python -m unittest test_module.TestClass
    b) $ python -m unittest test_module.TestClass.test_method
    c) $ python -m unittest test_method
    d) $ python -m unittest test_module

  11. assertRaises(exception)の役割は何ですか?
    a) 指定した例外が発生しないことを確認する
    b) 指定した例外が発生することを確認する
    c) 例外の詳細を表示する
    d) 例外を無視する

  12. -fオプションの役割は何ですか?
    a) テストを強制的に実行する
    b) 初回のエラーでテストを停止する
    c) テストの結果をファイルに保存する
    d) テストの実行を遅延させる

  13. assertIsNone(x)の役割は何ですか?
    a) xがTrueであることを確認する
    b) xがNoneでないことを確認する
    c) xがNoneであることを確認する
    d) xがFalseであることを確認する

  14. unittestでテストを実行する際、成功したアサーションの詳細はどうなりますか?
    a) 詳細が表示される
    b) 成功したテストの数が表示される
    c) 表示されない
    d) エラー情報と共に表示される

  15. tearDownClass()メソッドはいつ呼び出されますか?
    a) 各テストメソッドの実行後
    b) クラス内のテストが実行された後に1回だけ
    c) テストメソッドの実行前
    d) テストクラスの初期化時

  16. テストクラスのスーパークラスとして正しいものはどれですか?
    a) unittest.Test
    b) unittest.BaseTest
    c) unittest.TestCase
    d) unittest.TestSuite

解答:

  1. b
  2. b
  3. c
  4. b
  5. b
  6. b
  7. b
  8. b
  9. c
  10. b
  11. b
  12. b
  13. c
  14. c
  15. b
  16. c
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?