pytest でテストが見つからず実行できない(collected 0 items / no tests ran)
pytest は命名規則に合うファイル・関数・クラスだけを集める。
test_*.py か *_test.py のファイル、test で始まる関数、__init__ の無い Test で始まるクラスに揃え、pytest --collect-only で何が集まるかを確かめる。
公開:
要約
テストを書いたのに、pytest が 1 件も実行しないまま終わる。
============================= test session starts ==============================
rootdir: /app
collected 0 items
============================ no tests ran in 0.00s =============================pytest は、決まった命名規則に合うものだけをテストとして集める。
既定の規則は次のとおりだ。
- ファイル:
test_*.pyまたは*_test.py - 関数: 名前が
testで始まるもの(クラスの外) - クラス: 名前が
Testで始まり、__init__を持たないもの。
その中のtestで始まるメソッドが対象になる
1 件も集まらないとき、pytest は終了コード 5 で終わる。
CI ではこれが失敗として扱われるので、「テストは通っているはずなのにジョブが赤い」という形でも気付く。
よくある原因
- ファイル名が規則に合っていない:
check_math.pyやtests.pyは収集されない。 - 関数名・クラス名が規則に合っていない:
def check_add():やclass UserTest:は、ファイル名が正しくても対象にならない。 - テストクラスに
__init__がある: クラスごと外され、PytestCollectionWarning: cannot collect test class 'TestThing' because it has a __init__ constructorという警告だけが出る。
警告の一覧は結果の下にまとめて出るので見落としやすい。 - 設定や引数で外している:
python_filesに独自のパターンだけを書いた、norecursedirsにtestsを入れた、-kの条件にどのテストも合わない、のいずれでも 0 件になる(-kのときは1 deselectedのように表示される)。
解決策
1. 名前を規則に揃える
# tests/test_calc.py
def test_add():
assert 1 + 1 == 2
class TestCalc:
def test_sub(self):
assert 2 - 1 == 12. クラスの前準備は init 以外で行う
テストクラスではインスタンスの初期化を pytest に任せる。
前準備はフィクスチャか、各テストの前に呼ばれる setup_method に書く。
class TestThing:
def setup_method(self):
self.x = 1
def test_x(self):
assert self.x == 13. 収集結果を先に確かめる
pytest --collect-only -qテストを実行せずに、集まったテストの一覧だけを表示する。
0 件なら no tests collected と出るので、名前を直すたびにこれで確かめる。
4. 独自の命名を使うなら既定も並べて書く
check_*.py も集めたい場合は、python_files に既定の test_*.py と並べて書く。
# pytest.ini
[pytest]
python_files = test_*.py check_*.py既定の規則は、python_files を書いた時点で使われなくなる。check_*.py だけを書くと、今度は test_*.py が集まらなくなる。