きり丸の技術日記

技術検証したり、資格等をここに残していきます。

Pytestにてネストしたテストケースを作成する

JUnit 5だと@Nestedアノテーションを付与すると、テストクラス内にさらにテストクラスを用意できます。

Pytestでも同様にテストクラスをネストさせたかったのですが、ググってもすぐには出てこなかったので、自分のブログにまとめます。

環境

  • Pytest
    • 7.1.1

分かること

  • Pytestでネストしたテストクラスを書ける
  • @pytest.fixtureを使用してもネストしたテストクラスを書ける

ユースケース

テストクラスを特定の粒度ごとに作成する。

最低でも、テストクラス -> テストメソッドの1段落ネストしておくのはオススメです。

- テストクラス1
    - テストメソッド1
        - テストメソッド条件1
    - テストメソッド2
        - テストメソッド条件1
            - テストメソッド条件1-1
        - テストメソッド条件2
            - テストメソッド条件2-1
            - テストメソッド条件2-2

コード

次のコードで表現できます。ネストしたテストメソッドには、第1引数にselfを取ることさえ分かれば、簡単です。

@pytest.fixtureを使用する場合も、第2引数以降にマッピングされます。

import pytest

class TestNested:
    class TestMethodA:
        def test_1(self):
            assert 1 == 1

    class TestMethodB:
        class TestConditionA:
            def test_1(self):
                assert 1 == 1

        class TestConditionB:
            def test_1(self, condition_a):
                assert condition_a == 1

            def test_2(self, condition_b):
                assert condition_b == 2

@pytest.fixture
def condition_a():
    return 1

@pytest.fixture
def condition_b():
    return 2

なお、次の状態で-vをオプションで付与して実行すると、次のメッセージでテストの構造が分かりやすくなります。

tests/unit/models/test_nested.py::TestNested::TestMethodA::test_1
tests/unit/models/test_nested.py::TestNested::TestMethodB::TestConditionA::test_1
tests/unit/models/test_nested.py::TestNested::TestMethodB::TestConditionB::test_1
tests/unit/models/test_nested.py::TestNested::TestMethodB::TestConditionB::test_2

ソースコード

終わりに

pytest nestedと記載したところ、ParameterizedTestのStackOverFlowの記事しか出てこなかったので分かりませんでした。

調べようにもネストさせる書き方が当たり前ですので、検索するキーワードも思いつきませんでした。結局のところ、さまざまなPytestの記事やTwitterの検索等を手あたり次第調べてようやくわかりました。

普段からPython書いている人であれば簡単でしょうが、メインをPythonで扱わないので慣れることが難しいですね。動的型付言語はスクラッチ開発に強い印象ですが、慣れるまではスクラッチ開発は難しいので、ガンガン素振りしていきたいです。

参考情報