概要
pytestの設定
pytestはPythonのテスティングフレームワークの1つであり、Python標準モジュールに組み込まれているunittestと並んでPythonのテスト実装でよく使われています
単体テストは1つの関数に対して複数実装することが多く必然的に大量のテストを実行するため、単体テスト実行について事前に便利な設定をしてくことテストを便利に実行することができます。pytestを実行する上で関係する主な設定ファイルは下記があります。本記事ではpytest.ini
とconfest.py
について説明をします。
設定ファイル | 特徴 | 役割 |
---|---|---|
pytest.ini | – pytest固有の設定ファイル – テストディスカバリ、マーカー、警告制御などを管理 | – テスト全体の設定を集中管理 – カスタムマーカーやテスト対象ディレクトリの指定 |
conftest.py | – テスト共通のフィクスチャやフック関数を定義 – 同一ディレクトリやサブディレクトリで自動インポート | – 共通のセットアップ・クリーンアップ処理 – カスタムフックを通じたテストの動作拡張 |
pyproject.toml | – プロジェクト全体の設定ファイル – pytest以外のツールや依存関係も管理可能 | – [tool.pytest.ini_options]でpytest設定も可能 – 依存関係の一元管理 |
tox.ini | – マルチ環境テストの設定ファイル – Pythonバージョン別にテスト実行が可能 | – 複数環境でのテスト実行設定 – pytest設定を使い分けて異なる環境でテストを実行 |
pytest.ini
設定例
下記のpytest.iniでは3つの設定が記述されています。
コードの3行目のaddopts
ではテスト実行時の追加オプションを指定しており、コードの-v
は詳細表示を設定し、--maxfail=2
は2つ失敗したら停止する設定です。4行目のtestpaths
:ではテストを実行するディレクトリを指定しています。具体的にはtests
ディレクトリ内のテストを探索します。5行目のmarkers
では カスタムマーカーを定義します。ここではslow
マーカーを使って遅いテストを区別可能に設定しています。
# pytest.ini
[pytest]
addopts = -v --maxfail=2 # 詳細表示と最大失敗数の指定
testpaths = tests # テストディスカバリ対象のディレクトリ
markers =
slow: マーカー "slow" がついたテスト
テストディスカバリ
テストディスカバリとは、テストフレームワークがテストケース(テスト関数やテストクラス)を自動的に見つけ出して実行するためのプロセスです。pytest
では、特定の名前の規則(通常、ファイル名にtest_
や_test
を含むもの)に従ってテストファイルを検索し、見つけた関数やクラスをテストケースとして扱います。
例えば、pytest
はデフォルトで以下のようなパターンのファイル・関数をテストとして自動検出します:
- ファイル名が
test_*.py
または*_test.py
である - ファイル内の関数名が
test_
で始まる - クラス名が
Test
で始まり、その中の関数名がtest_
で始まる
confest.py
設定例
confest.pyの設定例を見ていきます。5-9行目ではsample_fixture
がというテスト内で利用できるフィクスチャが宣言されており、テスト実行前にセットアップ処理、実行後にクリーンアップ処理が行われます。
# conftest.py
import pytest
# 共通のフィクスチャを定義
@pytest.fixture
def sample_fixture():
print("\nフィクスチャのセットアップ")
yield "データ" # テストで使う値を返す
print("\nフィクスチャのクリーンアップ")
# フック関数
def pytest_sessionstart(session):
print("テストセッションが始まりました") # テスト開始時に呼ばれる
def pytest_sessionfinish(session, exitstatus):
print("テストセッションが終了しました") # テスト終了時に呼ばれる
# フック関数のカスタマイズ
def pytest_runtest_makereport(item, call):
# テストが失敗した場合のみ実行
if call.when == "call" and call.excinfo is not None:
print(f"テストケース {item.name} が失敗しました")
pytestのフック関数
フック関数とはテストの実行過程で特定のタイミングに自動的に呼び出されるpytestに組み込まれた関数です。
例えばテスト全体の開始時や終了時、または個々のテストが始まるとき・終わるときなど、テストの様々な段階に合わせて動作するフック関数が用意されています。これにより、例えばテストの前にデータベースを初期化したり、テストの終了後にログを保存したりといったことができます。またpytestではフック関数がカスタマイズすることも可能です。以下はその例です。
pytest_sessionstart
:テストセッションが始まるときに実行pytest_runtest_setup
:各テストの開始前に実行pytest_runtest_call
:各テストのメイン処理(関数やメソッドの呼び出し)時に実行pytest_sessionfinish
:テストセッションが終了したときに実行pytest_runtest_makereport
:各テストの終了時にその結果のレポートを作成するタイミングで
pytestのフック関数の詳細はこちらのpytest公式サイトをチェックしてみてください
confest.pyの有効範囲
conftest.py
は配置されたディレクトリとそのサブディレクトリにあるテストケースにのみ適用されます。そのため複数のディレクトリにconftest.py
が設置されている場合、それぞれのconftest.py
は配置されている同階層以下のテストケースにのみ適用されるようにスコープが制限されます。
3行目のtests/conftest.py
の設定内容は、tests/test_file1.py
とtests/sub_tests/
以下のすべてのテストに適用されます。また6行目のtests/sub_tests/conftest.py
の設定は、tests/sub_tests/test_file2.py
などsub_testsディレクトリ内にあるテストケースにのみ適用されます。
project/
├── tests/
│ ├── conftest.py # テスト共通設定A
│ ├── test_file1.py
│ └── sub_tests/
│ ├── conftest.py # テスト共通設定B
│ └── test_file2.py
まとめ
本記事ではpytestの設定ファイルであるpytest.ini
とconfest.py
について解説しました。設定ファイルといっても何を設定したいかで使用すべきファイルが変わります。本記事の内容を参考にご自身の環境に応じた設定ができるようになることを祈っています!