[小ネタ] pytestのparametrizeでパラメータ毎にfixture(setup/teardown)が実行されるか試してみた(できた)

Pythonのpytestでparametrizeを使うと、テストパターンを簡単に増やすことができます。 このとき、パラメータ毎にfixtureが実行されるのか?を試してみました。
2019.04.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

サーバーレス開発部の藤井元貴です。

pytestでテストをパラメータ化するときにparametrizeを使用します。

このとき、「fixture(setup/teardown)はテスト毎(パラメータ毎)に実行されるのか?」が気になったので試してみました。

使用想定としては、LocalStackでS3やDynamoDBのテストをするとき、パラメータ毎にS3やDynamoDBの内容をリセットするなどです。

  • setupで前提ファイルを作成する
  • teardownで前提ファイルを削除する

おすすめの方

  • pytestでparametrizeを使ってみたい
  • pytestでfixtureを使ってみたい

環境

項目 バージョン
macOS High Sierra 10.13.6
Python 3.6
pytest 4.3.1

やってみた

ディレクトリ構成

テスト対象のコード(src)とテストコード(tests)を明確にするため、次のようにしています。

.
├── src
│   └── my_module.py
└── tests
    ├── conftest.py
    └── test_my_module.py

テスト対象のコード

よくある感じの、加算するヤツです。

my_module.py

def sum(x ,y):
    return x + y

テストコード

まずはconftest.pyにfixtureを定義します。 処理の実行を確認できるようにするため、print文で開始(setup)と終了(teardown)を表示させます。

conftest.py

import pytest

@pytest.fixture
def aaaaa():
    print('\nsetup aaaaa()\n')
    yield
    print('\nteardown aaaaa()\n')

続いてテストコード本体です。 3パターンを試します。それぞれでfixtureが実行されれば期待通りです!

test_my_module.py

import pytest
from src.my_module import sum

class TestMyModule:

    @pytest.mark.parametrize("x, y, expected", [
        (1, 2, 3),
        (3, 4, 7),
        (5, 6, 11)
    ])
    @pytest.mark.usefixtures('aaaaa')
    def test_sum(self, x, y, expected):
        assert expected == sum(x, y)

テストする

標準出力(print文)の内容をターミナルに表示したいため、-sオプションを与えています。

$ python -m pytest tests/ -v -s
============================= test session starts ==============================
platform darwin -- Python 3.6.1, pytest-4.3.1, py-1.8.0, pluggy-0.9.0 -- /Users/fujii.genki/.pyenv/versions/3.6.1/bin/python
cachedir: .pytest_cache
rootdir: /Users/fujii.genki/Documents/app_test, inifile:
collected 3 items

tests/test_my_module.py::TestMyModule::test_sum[1-2-3] 
setup aaaaa()

PASSED
teardown aaaaa()


tests/test_my_module.py::TestMyModule::test_sum[3-4-7] 
setup aaaaa()

PASSED
teardown aaaaa()


tests/test_my_module.py::TestMyModule::test_sum[5-6-11] 
setup aaaaa()

PASSED
teardown aaaaa()

=========================== 3 passed in 0.04 seconds ===========================

しっかりと、テストケース(パラメータ毎)にfixtureが実行されていました!

参考