Python 独自fixture

Python学習【365日チャレンジ!】184日目のマスターU(@Udemy11)です。

マイナポイントの決済サービスの変更ができないことに怒り心頭だったのですが、一晩寝るとそんな怒りはどこへやら。。。

変更できると期待していた私が馬鹿だったってことで、今後は政府への期待は一ミリも持たないようにしたいと思います。

ほんと政府がやることって、桜の会にしても、アベノマスクにしてもどうしてこうも国民意識からかけ離れているんでしょうか?

半沢直樹のように、感謝して人のために仕事ができる人っていないのでしょうか?

それでは、今日もPython学習をはじめましょう。

昨日の復習

昨日は、pytestのfixtureのtmpdirの具体的な使い方を学習しました。

テストで一時ディレクトリを作成した後、終了後に一時ディレクトリを削除する使い方をコードの流れに沿って確認しました。

メインのファイルにディレクトリパスと名前を受け取って、文字列を書き込む関数を作成してテストしましたが、tmpdirなら一時ディレクトリを扱うことができて、そのディレクトリはテスト後に削除されるので、具体的な使い方がわかったかと思います。

tmpdirの具体的な使い方は昨日の記事を参考にしてください。

今日は、pytestの独自fixtureの使い方を学習します。

calculation.py

今回もテストするメインのファイルはcalculation.pyです。

class Cal(object):
    def add_and_double(self, x, y):
        if type(x) is not int or type(y) is not int:
            raise ValueError
        result = x + y
        result *= 2
        return result

昨日加えた関数は不要なので、計算する関数だけにしています。

conftest.py

独自のfixtureは、conftest.pyに記述することで、どのテストでも共通で利用することができるようになります。

超簡単にfixtureを使うコードを書いてみましょう。

import pytest


@pytest.fixture
def test_fix():
    return 'test fixture!!!'

pytestをインポートして、デコレーターを@pytest.fixtureにして、文字列のtest fixture!!!を返す関数test_fixを定義します。

test_calculation.py

テストを実行するファイルはtest_calculation.pyで、昨日加えたtmpdirを使ったテストは今回省きます。

conftest.pyで定義したtest_fixを実行するコードを付け加えます。

import calculation

class TestCal(object):

    @classmethod
    def setup_class(cls):
        cls.cal = calculation.Cal()

    def test_add_and_double(self, test_fix):
        print(test_fix)
        assert self.cal.add_and_double(1, 3) == 8

ハイライトしている9行目で引数に先程定義したtest_fixを引数にして10行目でtest_fixを出力しています。

test_add_and_doubleがテストされたときにtest_fix(test fixture!!!)が出力されます。

Python 独自fixture

今回定義したのは、文字列を出力するだけの単純なfixtureですが、次はもっと便利な使い方を学習しましょう。

yieldを使う

generatorで学習したyieldを使って値を渡すことができます。

独自fixtureでyieldを使うことの利点は、テストの前後になにかの処理をさせることができることです。

昨日学習したtmpdirと組み合わせたconftest.pyを書いてみました。

import os

import pytest


@pytest.fixture
def test_fix(tmpdir):
    with open(os.path.join(tmpdir, 'test.csv'), 'w') as t:
        print('start test')
        yield t
        print('finish test')

このコードでは、test_fix()にfixtureのtmpdirを指定して、一時ディレクトリのパスとファイル名をつなげてファイルを作成しています。

テストでは、yieldの値が渡されますが、テストの前後で、start testfinish testが出力されます。

またwith openによって、fixtureの中でファイルは閉じられて削除されるので、テストファイルの中でファイルを閉じる必要がなくなります。

テストファイルであるtest_calculation.pyのコードはそのままで、テストの実行結果は、次のようになります。

Python 独自fixture

テストの前とあとに定義した文字列が出力されているのがわかります。

慣れが必要

これまで学習してきたPythonでは、関数に引数を自分で指定しないとエラーが起こるのに、fixtureを指定すれば勝手に引数が渡されるので、最初のうちは、変な感じがするかと思います。

とはいえfixtureはpytestだけでなく、他のテストフレームでもよく使われるので、しっかりと理解を深めておく必要があります。

どんなことでも慣れてしまえば、違和感は感じなくなるので、やっぱり継続して学習することが大切です。

継続することって誰もができることなのですが、ずっと継続するのってやっぱり難しいんですよね。

ただ、難しいと言ってると難しいということが無意識に刷り込まれてしまうので、楽しみを見つけつつPython学習を継続しましょう。

それでは、明日もGood Python!