nikkie-ftnextの日記

イベントレポートや読書メモを発信

pytestでテストの前準備 〜setup_methodとフィクスチャ〜

はじめに

プロなんだから、nikkieです。

pytest素振りの中での学びをアウトプットします。

目次

TDDBC 2020より、前準備をDRYに

t-wadaさんと擬似的なペアプロFizzBuzzをTDDしていたnikkie氏1

各テストでFizzBuzz()というインスタンス化が登場している(重複している)ことに対処します。
https://www.youtube.com/live/Q-FJ3XmFlT8?si=NvIY90zAhQ5dPUFj&t=6486

JUnitでは@BeforeEachで前準備メソッドをアノテーション
各テストの前に前準備メソッドが実行され、コード上はFizzBuzz()インスタンス化)は1箇所で済みます。

unittestならsetUp

PythonのunittestではTestCaseのsetUpメソッドで実行できます。
https://docs.python.org/ja/3/library/unittest.html#unittest.TestCase.setUp

テストメソッドの直前に呼び出されます。

デフォルトの実装では何も行いません。

こんな感じになります。

class FizzBuzzTestCase(TestCase):
    def setUp(self):
        self.fizz_buzz = FizzBuzz()
    
    # 各テストでは self.fizz_buzz を使ってテストを書いていく

pytestではsetup_methodがある

今回は練習のためにpytestを使っていました。
やり方を調べると見つかったのがsetup_method

class TestFizzBuzz:
    def setup_method(self):
        self.fizz_buzz = FizzBuzz()

これで前準備を1箇所にできました!

TDDBC 2020より、テストコードでも仕様のネスト構造を表す

t-wadaさんとのセッションは、テストを動作するドキュメントにするパートへと進みます2
https://www.youtube.com/live/Q-FJ3XmFlT8?si=r9pRpwXXSEOH_CYJ&t=7421

そこで登場したのが、クラスのネスト!
仕様(TODOリスト)にはネスト構造があり、それをテストコードでも表していきます。
まさしくドキュメントになっていてすごいです👏

ネストするとsetup_methodはうまくいかない...

このとき、上記のsetup_methodはうまくいきません。
上位のクラスに1回ではなく、ネストした個々のクラスに定義する必要があるようでした。
それをするくらいなら個別にインスタンス化の方が簡単に思えました。

Pythonで試していたら、(まず動作するために)ネストの構造化のために前準備のDRYを諦めることになったのです。
※私の知識不足もあると思うので、フィクスチャ以外のやり方でもできるなどありましたら、ぜひ教えてください!

pytestのフィクスチャを使えばできるよ!

動作はさせたので、次は前準備のDRYを諦めたくないぞと調べる中で見つかったのが、やっとむさんのツイート。

フィクスチャ!
過去に触った経験が告げます、たしかにこれならいけそう!

@pytest.fixture
def fizz_buzz():
    return FizzBuzz()

class TestFizzBuzz:
    class Test_3の倍数のときは数の代わりにFizzに変換する:
        def test_3を渡すと文字列Fizzを返す(self, fizz_buzz):
            assert "Fizz" == fizz_buzz.convert(3)

前準備をフィクスチャにすると、クラスのネスト(inner class)があっても前準備をDRYにできました!🙌
全容はこちらです:

『テスト駆動Python 第2版』より フィクスチャ

3章でフィクスチャががっつり解説されます。
私は初版でフィクスチャを知り、「ほえ〜〜、めっちゃ便利なものを知れた〜!」となりました3

フィクスチャは実際のテスト関数の実行に先立って(場合によってはその後に)pytestが実行する関数です。(Kindle版 p.82)

pytestのフィクスチャは、pytestを他のテストフレームワークから際立たせるpytestならではの機能の1つです。(Kindle版 pp.84-85)

終わりに

pytestの素振りでフィクスチャによる前準備がとても便利だと気付きました

  • クラスをネストしてテストコードを構造化しても使える!
  • setup_methodも知ったが、クラスをネストしたときに私はうまく使えなかった

pytestならではの機能、フィクスチャ。
フィクスチャに習熟してpytestをうまく使っていきたいですね〜


  1. 詳しいバージョンです
  2. これは本当にすごくて、テストコードの捉え方が変わりました!
  3. (この記事では紹介していませんが)yieldを使って書くフィクスチャがめっちゃ便利だと思いました