Pytestの実行フローに介入し、テスト結果の詳細を取得・記録するには、conftest.pyにフック関数を実装します。特にpytest_runtest_logreportフックは、各テストステップ(setup, call, teardown)の完了時に呼び出され、テストの成否や実行時間などのメタデータを含むレポートオブジェクトを提供します。これを利用することで、テストケース名の抽出やカスタムログの出力が可能になります。
基本的な実装方法
このフック関数は引数としてreportオブジェクトを受け取ります。report.nodeidにはテストファイルのパスやテスト関数名を含む一意の識別子が格納されています。以下の例では、テストが実際に実行されるcallフェーズに限定して処理を行い、結果をコンソールに出力します。
# conftest.py
def pytest_runtest_logreport(report):
# テスト実行フェーズ(call)のみを対象とする
if report.when == "call":
if report.passed:
print(f"[PASS] {report.nodeid}")
elif report.failed:
print(f"[FAIL] {report.nodeid}")
elif report.skipped:
print(f"[SKIP] {report.nodeid}")
テスト関数名の抽出と詳細なログ记录
nodeidはパスを含む長い文字列となるため、テスト関数名のみを抽出したい場合は文字列分割を活用します。また、単なる成否だけでなく、エラー内容や実行時間(report.duration)なども取得できるため、ログの精密化に役立ちます。
# conftest.py
def pytest_runtest_logreport(report):
# 実行フェーズが 'call' の場合のみ処理を実行
if report.when != "call":
return
# ノードIDからテスト関数名のみを抽出(例: path/to/test_file.py::test_func -> test_func)
test_function_name = report.nodeid.split("::")[-1]
if report.failed:
# 失敗したケースの詳細なログ出力
print(f"テスト失敗: {test_function_name}")
print(f"実行時間: {report.duration:.4f}秒")
else:
# 成功したケースのログ出力
print(f"テスト成功: {test_function_name}")
このフックを導入することで、標準出力上で特定のテストが失敗した際に即座に識別できるようになり、デバッグ効率が向上します。reportオブジェクトには他にも失敗時の例外情報やトレースバックなどの属性が含まれており、これらを活用することでより高度なレポート機能を構築できます。