私はpytest のベストプラクティス少なくとも私は私はそう思うただし、pytest はモジュールを見つけることができません。現在のディレクトリが含まれていないようですPYTHONPATH
。
ソースファイル:
def add(x, y):
return x + y
テストファイル:
import pytest
from junk.ook import add
def test_add_true():
assert add(1, 1) == 2
そして、「p3」と呼ばれる Python 3 仮想環境を使用したシェル出力。
p3; pwd
/home/usr/tmp/junk
p3; ls
total 0
0 junk/ 0 tests/
p3; ls junk
total 4.0K
4.0K ook.py 0 __init__.py
p3; ls tests
total 4.0K
4.0K test_ook.py 0 __pycache__/
p3; pytest
============================= test session starts ==============================
platform linux -- Python 3.4.5, pytest-3.4.1, py-1.5.2, pluggy-0.6.0
rootdir: /home/usr/tmp/junk, inifile:
collected 0 items / 1 errors
==================================== ERRORS ====================================
______________________ ERROR collecting tests/test_ook.py ______________________
ImportError while importing test module '/home/usr/tmp/junk/tests/test_ook.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_ook.py:2: in <module>
from junk.ook import add
E ImportError: No module named 'junk'
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=========================== 1 error in 0.08 seconds ============================
def test_add_true():
assert add(1, 1) == 2
ただし、以下を実行すると正常に動作します。
p3; python -m pytest tests/
============================= test session starts ==============================
platform linux -- Python 3.4.5, pytest-3.4.1, py-1.5.2, pluggy-0.6.0
rootdir: /home/usr/tmp/junk, inifile:
collected 1 item
tests/test_ook.py . [100%]
=========================== 1 passed in 0.02 seconds ===========================
何が間違っているのでしょうか?
ベストアンサー1
pytest 7以降のアップデート:pythonpath
設定を使用する
最近、pytest
新しいコアプラグインが追加されsys.path
、pythonpath
設定値解決策ははるかに簡単になり、回避策は不要になりました。
pyproject.toml
例:
[tool.pytest.ini_options]
pythonpath = [
"."
]
pytest.ini
例:
[pytest]
pythonpath = .
パス エントリは rootdir を基準として計算されるため、この場合はディレクトリ.
が追加されます。junk
sys.path
複数のパスエントリも許可されます。レイアウトの場合
junk/
├── src/
| └── lib.py
├── junk/
│ ├── __init__.py
│ └── ook.py
└── tests
├── test_app.py
└── test_lib.py
構成
[tool.pytest.ini_options]
pythonpath = [
".", "src",
]
または
[pytest]
pythonpath = . src
lib
モジュールとjunk
パッケージの両方を に追加するのでsys.path
、
import junk
import lib
どちらも動作します。
元の回答
conftest.py
プロジェクトのルート ディレクトリに空のファイルを置くだけです。
$ pwd
/home/usr/tmp/junk
$ touch conftest.py
プロジェクトの構造は次のようになります。
junk
├── conftest.py
├── junk
│ ├── __init__.py
│ └── ook.py
└── tests
└── test_ook.py
ここで何が起きるかというと、pytest
が を検出するとconftest.py
、 を変更してsys.path
conftest モジュールからインポートできるようにします。そのため、conftest.py
ルートディレクトリに空の が見つかったため、はpytest
それを に追加することを強制されますsys.path
。この副作用として、junk
モジュールがインポート可能になります。