1. ホーム
  2. python

py.test が sys.path にアプリケーションのディレクトリを含むことを確認します。

2023-12-11 14:11:45

質問

私は以下のようなプロジェクトのディレクトリ構造を持っています(これはかなり標準的だと思います)。

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 を使ってインポートしようとするまでです。このとき、"No module named mypkg"というエラーが表示されました。少し調査してみると、どうやら py.test にあるテストファイルのディレクトリでテストを実行するようです。 sys.path でテストを実行しますが ではなく というディレクトリは 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を与え pip install -e . をこのプロジェクト用の virtualenv で実行します。 これが標準的な方法でしょう。

  • virtualenv があって setup.py がない場合のバリエーションとして、sys.path に projects ディレクトリを追加する venv の機能を使います、例. pew add . pew を使っている場合は add2virtualenv . を、virtualenv と virtualenvwrapper の拡張を使う場合は となります。

  • もし、常に sys.path 上のカレントワーキングディレクトリが好きなら、単に常に PYTHONPATH='' をシェルで指定します。 これは、python が現在の作業ディレクトリとして解釈する sys.path 上の空文字列を確保することです。 しかし、これは潜在的にセキュリティハザードです。

  • 私自身のお気に入りのハックは、py.testがconftestファイルをロードする方法を悪用することです: 空の conftest.py をプロジェクトのトップレベルディレクトリに置くことです。

py.testがこのように振る舞う理由は、インストールされたパッケージに対して、チェックアウトのtests/ディレクトリにあるテストを簡単に実行できるようにするためです。 もし無条件にプロジェクトディレクトリをPYTHONPATHに追加するならば、これはもう不可能でしょう。