私は次のようなプロジェクトディレクトリ構造を持っています(これはかなり標準的だと思います):
my_project
setup.py
mypkg
__init__.py
foo.py
tests
functional
test_f1.py
unit
test_u1.py
テストフレームワークにpy.testを使用していますが、py.test tests
ディレクトリにいるときにmy_project
を実行してテストを実行できると期待しています。テストでimport mypkg
を使用してアプリケーションコードをインポートしようとするまで、これは実際に機能します。その時点で、「mypkgという名前のモジュールはありません」というエラーが表示されます。少し調べてみると、py.test
はsys.path
にあるテストファイルのディレクトリでテストを実行しているようですが、notはpy.test
であったディレクトリから実行。
これを回避するために、次のコードを含むconftest.py
ファイルをtests
ディレクトリに追加しました。
import sys, os
# Make sure that the application source directory (this directory's parent) is
# on sys.path.
here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, here)
これは機能しているように見えますが、テストでアプリケーションコードが表示されることを確認する良い方法ですか?これを達成するためのより良い方法はありますか、それとも私は自分のプロジェクトをどのように構築するかについて何か間違ったことをしていますか?
私はpy.test
(たとえば、pip
)を使用する他のプロジェクトを見ましたが、このようなことをするコードは見られませんが、py.test tests
を実行すると動作するようですそこ。理由はよくわかりませんが、もっと簡単な方法で同じ結果が得られるのではないかと心配しています。
py.test
のドキュメントを調べましたが、この問題の説明や、対処するための推奨されるアプローチはわかりません。
あなたが言うように、py.testは基本的にPYTHONPATHが正しくセットアップされていることを前提としています。これを達成するにはいくつかの方法があります。
プロジェクトにsetup.pyを与え、このプロジェクトのvirtualenvで_pip install -e .
_を使用します。これはおそらく標準的な方法です。
Virtualenvはあるがsetup.pyがない場合のバリエーションとして、venvの機能を使用してsys.pathにプロジェクトディレクトリを追加します。 pewを使用する場合は_pew add .
_、virtualenvとvirtualenvwrapperの拡張を使用する場合は_add2virtualenv .
_。
Sys.pathの現在の作業ディレクトリが常に好きな場合は、シェルで_PYTHONPATH=''
_をいつでもエクスポートできます。これは、sys.pathの空の文字列がpython現在の作業ディレクトリとして解釈されることを保証します。これは、潜在的にセキュリティ上の危険性があります。
私自身のお気に入りのハック、py.testがconftestファイルをロードする方法を悪用します。プロジェクトのトップレベルディレクトリに空の_conftest.py
_を入れます。
Py.testがこのように動作する理由は、インストールされたパッケージに対するチェックアウトのtests /ディレクトリでテストを簡単に実行できるようにするためです。プロジェクトディレクトリを無条件でPYTHONPATHに追加する場合、これはもう不可能です。
here のように、答えは実際にははるかに簡単です。
必要なことは、__init__.py
をテストディレクトリとその各サブディレクトリに追加します。
tests/__init__.py
tests/functional/__init__.py
tests/unit/__init__.py
簡単な方法は、terminal/cmdで親ディレクトリがある場所にディレクトリを変更することです(この場合はcd C:/.../my_project
)。
次に、実行します:python -m pytest --cov=mypkg tests
PYTHONPATH
環境変数をいじる必要はありません。 python -m pytest
で実行すると、現在のディレクトリがsys.path
に自動的に追加されます。