概要
pytest は成熟したフル機能の Python テストツールで、fixture のパラメータ化、豊富なプラグインアーキテクチャ、テストの自動検出をサポートしています。詳細なアサーション失敗情報を提供し、デバッグを容易にします。
README プレビュー
.. image:: https://github.com/pytest-dev/pytest/raw/main/doc/en/img/pytest_logo_curves.svg\n :target: https://docs.pytest.org/en/stable/\n :align: center\n :height: 200\n :alt: pytest\n\n\n------\n\n.. image:: https://img.shields.io/pypi/v/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg\n :target: https://anaconda.org/conda-forge/pytest\n\n.. image:: https://img.shields.io/pypi/pyversions/pytest.svg\n :target: https://pypi.org/project/pytest/\n\n.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/main/graph/badge.svg\n :target: https://codecov.io/gh/pytest-dev/pytest\n :alt: Code coverage Status\n\n.. image:: https://github.com/pytest-dev/pytest/actions/workflows/test.yml/badge.svg\n :target: https://github.com/pytest-dev/pytest/actions?query=workflow%3Atest\n\n.. image:: https://results.pre-commit.ci/badge/github/pytest-dev/pytest/main.svg\n :target: https://results.pre-commit.ci/latest/github/pytest-dev/pytest/main\n :alt: pre-commit.ci status\n\n.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg\n :target: https://www.codetriage.com/pytest-dev/pytest\n\n.. image:: https://readthedocs.org/projects/pytest/badge/?version=latest\n :target: https://pytest.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/badge/Discord-pytest--dev-blue\n :target: https://discord.com/invite/pytest-dev\n :alt: Discord\n\n.. image:: https://img.shields.io/badge/Libera%20chat-%23pytest-orange\n :target: https://web.libera.chat/#pytest\n :alt: Libera chat\n\n\nThe ``pytest`` framework makes it easy to write small tests, yet\nscales to support complex functional testing for applications and libraries.\n\nAn example of a simple test:\n\n.. code-block:: python\n\n # content of test_sample.py\n def inc(x):\n return x + 1\n\n\n def test_answer():\n assert inc(3) == 5
FAQ (5)
トラブル対応「py:class reference target not found: pluggy._compat.DistFacade」という警告で Sphinx ドキュメントのビルドが失敗する場合の修正方法
このエラーは、Pluggy 1.7.0 でドキュメントをビルドする際(例:pytest で tox -e docs を実行)に発生します。これは、PluginManager.list_plugin_distinfo の docstring が非公開で文書化されていないクラス pluggy._compat.DistFacade を参照しており、-W によってその警告が失敗として扱われることが原因です。修正方法:Sphinx の conf.py の nitpick_ignore にこの非公開クラスを追加します:
nitpick_ignore = [
# ... 既存のエントリー ...
("py:class", "pluggy._compat.DistFacade"),
]
これにより、Pluggy をピン留めしたりダウングレードしたりすることなく、他のすべてのターゲットに対する厳密な参照チェックを維持できます。注意:Pluggy 1.6.0 へのダウングレードは有効な回避策ではありません。他の非公開の Pluggy 型参照の警告が発生するためです。
トラブル対応ネストされたシーケンスを比較する際に発生する pytest.approx() の AttributeError: 'tuple' object has no attribute 'expected' を修正する方法
pytest.approx() は、タプルのリストのようなネストされたデータ構造 (例: pytest.approx([(2.0, 2.0)])) をサポートしていません。pytest <= 9.1.1 では、アサーションのレポート中に紛らわしい AttributeError: 'tuple' object has no attribute 'expected' が発生します。
回避策:
1. 比較する前に構造をフラット化する: assert [x for t in sut() for x in t] == pytest.approx([2.0, 2.0])
2. 要素を個別に比較する: result = sut(); assert result[0] == pytest.approx((2.0, 2.0)) (数値のみのフラットなタプル/リスト 1 つであればサポートされています)
3. 数値の 2 次元データには、approx が処理できる numpy 配列を使用してください。
pytest 9.2+ (PR #14934 による修正) にアップグレードしても、ネストされた構造が動作するようになるわけではありませんが、不可解な AttributeError が明確なエラー TypeError: pytest.approx() does not support nested data structures に置き換わります。上記のように比較の構造を変更する必要は依然としてあります。
トラブル対応pytest の exconly(tryshort=True) で 'AssertionError: ' が削除されない場合の修正方法
これは pytest 8.0.2 および関連バージョンにおけるバグです:ExceptionInfo.for_later() は例外がキャプチャされる前に ExceptionInfo を生成し、その assertion striptext を一切設定しないため、exconly(tryshort=True) は AssertionError: プレフィックスを保持したままになります。
例外の値を直接使用してください:
with pytest.raises(AssertionError) as exc_info:
raise AssertionError("message")
message = str(exc_info.value)
assert message == "message"
exconly() の動作を維持する必要がある場合は、キャプチャされた例外から ExceptionInfo を再構築してください:
from pytest import ExceptionInfo
message = ExceptionInfo.from_exception(
exc_info.value
).exconly(tryshort=True)
Python 3.9 以降で使用できる文字列による回避策は次のとおりです:
message = str(exc_info.value).removeprefix("AssertionError: ")トラブル対応pytest がテストクラスを収集するにもかかわらず、ABCMeta の抽象メソッドを継承している場合にテストが見つからないと報告するのはなぜですか?
pytest 8.3+ では、抽象テストクラスはコレクション時にスキップされます。TestFoo クラスは継承された test_foo メソッドを実装していないため抽象クラスのままとなっており、pytest はそこから何も収集せずに暗黙的にスキップします。
未実装の抽象メソッドを確認してください:
python -c "import your_test_module; print(your_test_module.TestFoo.__abstractmethods__)"
これは {'test_foo'} と出力されるはずです。具象テストクラスですべての抽象メソッドを実装して修正します:
class TestFoo(AbstractTestFoo):
def test_foo(self):
assert True
その後、pytest を再度実行してください。クラスが意図的に抽象クラスである場合、または収集されるべきでない場合は、名前が Test で始まらないように変更するか、__test__ = False を設定してください。暗黙的にスキップされる抽象クラスに対する pytest の警告は、issue #13546 およびドラフト PR #15082 で追跡されていました。
トラブル対応テストクラスが抽象メソッドを継承しているときに、pytestが'collected 0 items'と報告するのはなぜですか?
TestFoo は test_foo を実装せずに継承しているため、依然として抽象クラスのままです。Pytest は収集時に抽象クラスをスキップするため、テストインスタンスもテストメソッドも収集されません。具象サブクラスでこの抽象メソッドを実装してください:
class TestFoo(AbstractTestFoo):
def test_foo(self):
assert True # ここにテストを書く
次のコマンドで収集を確認してください:
pytest --collect-only
これで TestFoo::test_foo が一覧に表示されるはずです。pytest 9.1.1 では、この状態はサイレントにスキップされます。収集時に失敗したり警告を発したりする動作は、提案された変更にすぎませんでした。