演習
この演習では、pytest
と parametrize を使用して関数をテストします。 次に、テスト クラスを更新して、setup()
メソッドと teardown()
メソッドの代わりにフィクスチャを使用します。
parametrize を使用してフィクスチャを操作すると、テストを作成または更新するときに柔軟性を高めることができます。
ステップ 1 - この演習用のテスト ファイルを追加する
test_advanced.py という新しいテスト ファイルを作成し、以下のコードを追加します。
def str_to_bool(string): if string.lower() in ['yes', 'y', '1']: return True elif string.lower() in ['no', 'n', '0']: return False
関数
str_to_bool()
は入力として文字列を受け取り、内容に応じてTrue
またはFalse
の値を返します。同じファイルに、関数
str_to_bool()
用のテストを追加します。 最初にすべての true 値をテストするためにpytest.mark.parametrize()
を使用します。import pytest @pytest.mark.parametrize("string", ['Y', 'y', '1', 'YES']) def test_str_to_bool_true(string): assert str_to_bool(string) is True
次に、false 値を使用した別のテストを追加します。
@pytest.mark.parametrize("string", ['N', 'n', '0', 'NO']) def test_str_to_bool_false(string): assert str_to_bool(string) is False
True
とFalse
の両方の戻り値に対して可能なすべての入力をカバーするテストが 2 つあります。
注
実際のコードと同じファイル内にテストを含めるのは一般的ではありません。 わかりやすくするために、この演習の例では、同じファイルに実際のコードが含まれています。 実際の Python プロジェクトでは、テストしているコードから、ファイルとディレクトリによってテストが分離されています。
ステップ 2 - テストを実行し、レポートを探索する
テストを追加した後、次のステップでは、pytest
を実行して出力を検査します。 詳細度の増加フラグ (-v
) を使用して、すべての入力値が個別のテストとして扱われているのを確認できるようにします。
$ pytest -v test_avanced.py
============================= test session starts ==============================
Python 3.9.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /private
collected 8 items
test_advanced.py::test_str_to_bool_true[Y] PASSED [ 12%]
test_advanced.py::test_str_to_bool_true[y] PASSED [ 25%]
test_advanced.py::test_str_to_bool_true[1] PASSED [ 37%]
test_advanced.py::test_str_to_bool_true[YES] PASSED [ 50%]
test_advanced.py::test_str_to_bool_false[N] PASSED [ 62%]
test_advanced.py::test_str_to_bool_false[n] PASSED [ 75%]
test_advanced.py::test_str_to_bool_false[0] PASSED [ 87%]
test_advanced.py::test_str_to_bool_false[NO] PASSED [100%]
============================== 8 passed in 0.01s ===============================
記述したテスト関数は 2 つだけですが、pytest
では関数 parametrize()
のおかげで合計で 8 つのテストを作成できました。
ステップ 3 - 既存のテストをフィクスチャに移植する
test_advanced.py ファイルに新しいクラス ベースのテストを追加します。 このテストでは、テキストを含む一時ファイルを作成する関数
setup()
とteardown()
を使用する必要があります。 各テストの後、ファイルは削除されます。 次のようになります。import os class TestFile: def setup(self): with open("/tmp/done", 'w') as _f: _f.write("1") def teardown(self): try: os.remove("/tmp/done") except OSError: pass def test_done_file(self): with open("/tmp/done") as _f: contents = _f.read() assert contents == "1"
このテスト クラスはファイルを作成しますが、/tmp/ パスがすべてのシステムに存在すると保証されるわけではないので、問題があります。
以下のように
pytest
tmpdir()
フィクスチャを使用してファイルに書き込みを行いパスを返すフィクスチャを作成します。import pytest @pytest.fixture def tmpfile(tmpdir): def write(): file = tmpdir.join("done") file.write("1") return file.strpath return write
tmpfile()
フィクスチャでは Pytest のtmpdir()
フィクスチャを使用します。これにより、テストの完了後に消去される有効な一時ファイルが保証されます。ヘルパー メソッドの "
TestFile
" フィクスチャを使用するように クラスを更新します。class TestFile: def test_f(self, tmpfile): path = tmpfile() with open(path) as _f: contents = _f.read() assert contents == "1"
このテスト クラスでは、一時ファイルが作成され、アサーションが機能するための適切な内容が含まれていることを確認できるようになりました。
作業を確認
これで、次のコードを含む test_advanced.py という名前の Python ファイルが作成されます。
- 文字列を受け取り、文字列の内容に応じてブール値を返す関数
str_to_bool()
。 - 関数
str_to_bool()
のパラメーター化された 2 つのテスト。1 つはTrue
値をテストし、もう 1 つはFalse
値をテストします。 -
pytest
フィクスチャを使用して、いくつかの内容を含む一時tmpdir()
ファイルを作成するカスタム フィクスチャ。 - カスタム
tmpfile()
フィクスチャを使用してファイルを作成するテスト クラス。
すべてのテストが、ターミナルで実行したときにエラーなしで成功する必要があります。