pytest で「fixture 'xxx' not found」が出てフィクスチャを使えない
テストが要求したフィクスチャが、そのテストから見える範囲に定義されていない。
conftest.py の置き場所、別ファイルでの定義、プラグインの入れ忘れ、綴り違いのどれかで、pytest --fixtures の一覧で切り分けられる。
公開:
要約
テスト関数の引数に書いた名前のフィクスチャが見つからないと、テストは実行前のセットアップで ERROR になる。
file /app/tests/api/test_api.py, line 1
def test_get(client):
E fixture 'client' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, ...
> use 'pytest --fixtures [testpath]' for help on them.公式ドキュメントのとおり、フィクスチャが使えるかどうかは「テストの側から見て、定義された範囲に入っているか」で決まる。conftest.py に書いたフィクスチャは、その conftest.py があるディレクトリとその配下のテストにだけ見える。available fixtures の一覧に目的の名前が無ければ、定義はテストから見えていない。
よくある原因
conftest.pyの場所がずれている:tests/db/conftest.pyに書いたフィクスチャは、tests/api/test_api.pyからは見えない。
兄弟のディレクトリは範囲の外になる。- テストファイルの中で定義している:
test_one.pyに書いたフィクスチャはtest_one.pyのテストだけが使える。
同じディレクトリのtest_two.pyから要求すると not found になる。
クラスの中で定義したフィクスチャも、そのクラスのテストに限られる。 - プラグインを入れていない:
mockerは pytest-mock が提供するフィクスチャで、pytest 本体には無い。
CI 用の依存に入れ忘れると、手元では通るのに CI だけ落ちる。 - 名前の綴りが違う: 引数
clinetはフィクスチャclientとは別物として扱われる。
ファイル名をconftest.py以外(confest.pyなど)にすると、中身は読み込まれない。
解決策
1. conftest.py を共通の上位ディレクトリへ移す
フィクスチャを使うテストが tests/api/ と tests/db/ にまたがるなら、両方を含む tests/ に置く。
tests/
├── conftest.py # client はここに置く
├── api/
│ └── test_api.py
└── db/
└── test_db.pyconftest.py のフィクスチャは、テストファイル側で import しなくても使える。
階層ごとに conftest.py を置いた場合は、各階層のフィクスチャがその配下のテストに加わる。
2. 共有するフィクスチャは conftest.py に書く
# tests/conftest.py
import pytest
@pytest.fixture
def user():
return {"name": "alice"}1 つのテストファイルでしか使わないフィクスチャは、そのファイルに置いたままでよい。
3. プラグインを依存に入れる
pip install pytest-mockプラグインのフィクスチャは、インストールするだけでテスト全体から使えるようになる。requirements-dev.txt などの開発用依存にも書いておく。
4. 見えているフィクスチャを一覧で確かめる
pytest --fixtures tests/api/test_api.pyfixtures defined from conftest の見出しの下に、名前と定義場所(client -- tests/conftest.py:3 のような形)が並ぶ。
ここに出てこなければ、そのテストからは見えていない。
名前が出ているのに not found になるなら、テスト側の引数の綴りを確かめる。