nikkie-ftnextの日記

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

pytestでテストケースの関数ではなく、フィクスチャをパラメタ化する

はじめに

かがみの孤城のシネコン、よかった😭👏👏 nikkieです

pytestについて、Today(※最近) I Learnedです

目次

パラメタ化テスト

現在時刻が関わるユニットテストから、テスト容易性設計を学ぶ - t-wadaのブログ

ほぼ同じテスト内容でデータだけを変えたテストメソッドを(列挙であれループであれ)書いているときに、テストメソッドにパラメータを渡せればいいのに、と感じることがあると思います。

Parameterized Test とは、まさに似たようなテストメソッドをテストデータだけ変えて複数件実行する手段

各種テストフレームワークで対応しており、pytestではこのように書きます。
pytest.mark.parametrize tips 2選 〜クラスもデコレートできる・複数積んでパラメタの組合せを自動化できる〜 - nikkie-ftnextの日記1

import pytest


@pytest.mark.parametrize(
    "test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)]
)
def test_eval(test_input, expected):
    assert eval(test_input) == expected

フィクスチャのパラメタ化

『テスト駆動Python 第2版』を読んでいて知りました(5.3)。

書籍を元に用意したサンプルです。

  • パラメタ化するフィクスチャにはrequest引数をもたせる
  • pytest.fixtureデコレータのparams引数に全てのパラメタを渡す
    • request.paramでパラメタ1つ1つにアクセスできる

print()関数が出力した部分を示します

% pytest -s test_fixture_params.py

Run common fixture
awesome fixture: 'kokoro'
.Run common fixture
awesome fixture: 'rion'
.

.が成功したテストケースを示しています。

  • awesomeフィクスチャが"kokoro"を返したときに、test_1_equals_1を実行
  • awesomeフィクスチャが"rion"を返したときに、test_1_equals_1を実行

フィクスチャを使ってパラメタ化できています!

展望

@pytest.mark.parametrize()を知っていた身には、フィクスチャのパラメタ化は使い所がいま一つ分かっていません。
ですが、『テスト駆動Python 第2版』を読んでいて見つけた以下がヒントになりそうです。

データベース接続やファイルを開くための処理は、フィクスチャのパラメータ化であればフィクスチャ内に記述できる。関数のパラメータ化を使う場合は、こうした処理もテスト関数内に記述しなければならなくなる。(Kindle版 p.163 注1)

pytestのフィクスチャまわりを見ているのは、「自作ライブラリ sphinx-new-tab-link のテストコードは、pytestの知識があればもっとDRYにできるのではないか」と思われたからです2
フィクスチャのパラメタ化は試しているところで、続くエントリで取り上げるかもしれません。

ドキュメントはこちらですね(積ん読
https://docs.pytest.org/en/stable/how-to/fixtures.html#parametrizing-fixtures