pytestの特徴
1. 簡潔な構文
pytestでは、テストケースの記述が非常に簡単です。assert
文を利用して期待値を記述するだけで済み、特別なAPIや記述形式を学ぶ必要がほとんどありません。
def test_addition():
assert 1 + 1 == 2
この簡潔な構文により、テストコードの可読性が向上し、開発者が効率的にテストを記述できます。
2. 多彩なプラグイン
pytestはプラグインベースの設計を採用しており、多様なプラグインをインストールして機能を拡張できます。
- pytest-cov: テストカバレッジの測定を行う。
- pytest-xdist: 並列テスト実行でテスト時間を短縮。
- pytest-html: テスト結果をHTML形式でレポートとして出力。
これらのプラグインを組み合わせることで、特定の要件に合わせた柔軟なテスト環境を構築できます。
3. 直感的なテスト結果
pytestは、テストの実行結果を色分けして表示するため、成功したテストと失敗したテストが一目でわかります。また、失敗時にはエラーの詳細が自動的に出力され、原因特定が容易です。
==================== FAILURES ====================
____________________ test_addition ____________________
def test_addition():
> assert 1 + 1 == 3
E assert 2 == 3
test_sample.py:3: AssertionError
このわかりやすい出力により、デバッグの効率が大幅に向上します。
4. 柔軟なフィクスチャ機能
フィクスチャは、テストの実行前後に必要な準備やクリーンアップを管理するための仕組みです。たとえば、テスト用のデータセットや一時的なリソースを簡単にセットアップできます。
import pytest
@pytest.fixture
def sample_data():
return {"key": "value"}
def test_fixture_usage(sample_data):
assert sample_data["key"] == "value"
フィクスチャを活用すると、テストコードがシンプルになり、再利用性も高まります。
pytestのインストール
pytestはpipで簡単にインストールできます。
pip install pytest
インストール後、以下のコマンドでバージョン確認が可能です。
pytest --version
pytestの基本的な使い方
1. テストファイルとテスト関数の命名規則
pytestでは、以下の命名規則に従う必要があります:
- テストファイル:
test_
で始まるファイル名(例:test_sample.py
) - テスト関数:
test_
で始まる関数名
2. シンプルなテストの記述
# test_sample.py
def test_addition():
assert 1 + 1 == 2
def test_subtraction():
assert 5 - 3 == 2
上記のコードを以下のコマンドで実行します。
pytest
3. テスト結果の出力例
テスト成功時:
==================== test session starts ====================
collected 2 items
test_sample.py .. [100%]
==================== 2 passed in 0.03s =====================
テスト失敗時:
==================== FAILURES ====================
____________________ test_addition ____________________
def test_addition():
> assert 1 + 1 == 3
E assert 2 == 3
test_sample.py:3: AssertionError
==================== 1 failed in 0.03s =====================
pytestのテスト結果の見方
pytestを実行すると、コマンドラインにテスト結果が出力されます。この結果を正しく理解することで、失敗したテストやその原因を迅速に特定できます。
pytestの出力は大きく以下のセクションに分かれています:
- セッション開始情報
- テスト実行の進行状況
- 成功/失敗したテストの詳細
- セッション終了情報
1. セッション開始情報
テストの実行が始まると、セッション情報が出力されます。
==================== test session starts ====================
platform darwin -- Python 3.10.0, pytest-7.0.1, pluggy-1.0.0
rootdir: /path/to/project
collected 3 items
- platform: 実行環境(OS、Pythonのバージョンなど)
- rootdir: テストのルートディレクトリ
- collected: 実行対象のテストケースの数
2. テスト実行の進行状況
テストの進行状況が1行ずつ表示されます。
test_sample.py .F. [100%]
-
.
: テスト成功を表します。 -
F
: テスト失敗を表します。 -
[100%]
: 実行が全体の何パーセント完了したかを示します。
例:
test_math.py .F.. [100%]
この例では、
- 最初のテストは成功
- 2番目のテストは失敗
- その後の2つのテストは成功
3. 成功/失敗したテストの詳細
テストが失敗した場合、その詳細が出力されます。
==================== FAILURES ====================
____________________ test_addition ____________________
def test_addition():
> assert 1 + 1 == 3
E assert 2 == 3
test_sample.py:3: AssertionError
- FAILURES: 失敗したテストのリスト
- テスト関数名: どのテストが失敗したかを表示
-
エラー内容:
-
E assert 2 == 3
: 期待値と実際の値が異なるため、AssertionErrorが発生 - ファイル名と行番号(例:
test_sample.py:3
)が示され、エラーの発生箇所が特定可能
-
4. セッション終了情報
セッション終了時には、以下の統計情報が出力されます。
==================== 1 failed, 2 passed in 0.03s ====================
- 1 failed: 失敗したテストの数
- 2 passed: 成功したテストの数
- 0.03s: テスト実行に要した時間
これにより、テスト全体の結果を簡単に把握できます。
高度な出力オプション
pytestには、テスト結果を詳細に表示するオプションがあります。
1. 詳細モード (-v)
詳細モードでは、各テストケースの名前と結果がすべて表示されます。
pytest -v
出力例:
==================== test session starts ====================
collected 3 items
test_sample.py::test_addition PASSED [ 33%]
test_sample.py::test_subtraction FAILED [ 66%]
test_sample.py::test_multiplication PASSED [100%]
==================== FAILURES ====================
...
2. 失敗のみ再実行 (--lf)
最後に失敗したテストのみを再実行できます。
pytest --lf
3. 成功したテストを省略 (--failed-first)
失敗したテストを優先的に実行します。
pytest --failed-first
4. HTMLレポートの生成
テスト結果をHTML形式で保存するには、pytest-html
プラグインを使用します。
pip install pytest-html
pytest --html=report.html
高度なpytestの機能
1. フィクスチャ (Fixtures)
フィクスチャは、テストの実行前後に必要な準備や後処理を行うための仕組みです。たとえば、データベース接続のセットアップやテストデータの生成などに使用します。
基本的なフィクスチャの例
import pytest
@pytest.fixture
def sample_data():
return {"key": "value"}
def test_fixture_usage(sample_data):
assert sample_data["key"] == "value"
スコープを指定する
フィクスチャのスコープを指定することで、実行範囲を制御できます。
-
function
: デフォルト。各テスト関数で1回実行。 -
class
: クラス単位で1回実行。 -
module
: モジュール単位で1回実行。 -
session
: テストセッション全体で1回実行。
@pytest.fixture(scope="module")
def db_connection():
conn = create_db_connection()
yield conn
conn.close()
2. マーク (Marks)
マークは特定のテストケースにラベルを付けて選択的に実行したり、条件付きで実行を制御する機能です。
基本的なマークの使用
import pytest
@pytest.mark.slow
def test_slow_function():
import time
time.sleep(5)
assert True
特定のマーク付きテストのみを実行:
pytest -m slow
条件付きスキップ
条件によってテストをスキップすることが可能です。
@pytest.mark.skipif(sys.version_info < (3, 10), reason="Python 3.10以上が必要")
def test_requires_python_310():
assert True
3. パラメータ化
同じテストケースで異なる入力データを使いたい場合、パラメータ化を活用することで効率的にテストを記述できます。
基本的なパラメータ化の例
import pytest
@pytest.mark.parametrize("a,b,result", [
(1, 1, 2),
(2, 3, 5),
(3, 5, 8),
])
def test_addition(a, b, result):
assert a + b == result
4. フック (Hooks)
pytestは、テストの実行前後に独自の処理を挟むためのフックを提供しています。これを使うことで、柔軟なテスト実行のカスタマイズが可能です。
フックの基本的な例
conftest.py
ファイルに以下のように記述します:
def pytest_runtest_setup(item):
print(f"Setting up: {item.name}")
フックの用途
- テスト環境の初期化
- カスタムロギングの実装
- 特定条件でのテストスキップ
5. プラグインの活用
pytestには多くの公式およびサードパーティ製プラグインがあり、テスト環境を拡張できます。
代表的なプラグイン
-
pytest-cov: テストカバレッジを測定
pip install pytest-cov pytest --cov=your_package
-
pytest-xdist: 並列テスト実行をサポート
pip install pytest-xdist pytest -n auto
-
pytest-html: テスト結果をHTMLレポートとして出力
pip install pytest-html pytest --html=report.html