2016-07-06 28 views
1

Pythonテストで相対パスが機能しないのはなぜですか?

project\tests\test_fo.py 

from ..scripts import foo 

def test_one(): 
    assert 0 

私は

cd C:\project 
C:\virtualenvs\test_env\Scripts\activate 
python setup.py install 
python setup.py test 

EとValueError行うとき、私は、次のエラーを取得する次のように私のテストファイルが見え

project\ 
project\setup.py 
project\scripts\foo.py 
project\scripts\bar.py 
project\scripts\__init__.py 
project\tests\test_foo.py 
project\tests\__init__.py 

次のように私のディレクトリ構成は次のとおりですしようと相対トップパッケージを超えてインポート

私は間違って何をしていますか? これは

setup(
    name = 'project', 
    setup_requires=['pytest-runner'], 
    tests_require=['pytest'], 
    packages = ["scripts","tests"], 
    package_data={ 
      'scripts': ['*.py'], 
      'tests': ['*.py'], 
     }, 
) 

答えて

3

相対輸入は唯一パッケージ内を働く私のsetup.pyです。 scriptsはパッケージであり、testsですが、projectディレクトリではありません。これにより、scriptstestsトップレベルパッケージとなります。相対的な構文を使用して他のトップレベルの名前を参照することはできません。

さらに、パッケージではテストは実行されません。テストランナーはモジュールをインポートします。tests.test_fooモジュールではありません。したがって、はPythonに関する限りです。test_fooは最上位モジュールです。

scriptsはトップレベルの名前です。その名前を直接使用してください。ただし、projectディレクトリをsys.pathに追加する必要があります。あなたがpython setup.pyを実行したときに

from scripts import foo 

注しかし現在の作業ディレクトリが追加されていること:絶対パスでscriptsからインポート

import os 
import sys 

TEST_DIR = os.path.dirname(os.path.abspath(__file__)) 
PROJECT_DIR = os.path.abspath(os.path.join(TEST_DIR, os.pardir)) 
sys.path.insert(0, PROJECT_DIR) 

:あなたがあなたのtest_foo.pyファイルの先頭にそうすることができますとにかくsys.pathだから、scriptssys.pathでフィディ

また、pytestはとなります。すでにの作業を行います。与えられたテストファイルに対して、でない最初の親ディレクトリが__init__.pyファイルであることが確認されます。sys.pathです。あなたの場合はproject/ディレクトリなので、再度scriptsから直接インポートすることができます。Good Practicesを参照してください:

If pytest finds a “a/b/test_module.py” test file while recursing into the filesystem it determines the import name as follows:

  • determine basedir : this is the first “upward” (towards the root) directory not containing an __init__.py . If e.g. both a and b contain an __init__.py file then the parent directory of a will become the basedir.
  • perform sys.path.insert(0, basedir) to make the test module importable under the fully qualified import name.
  • import a.b.test_module where the path is determined by converting path separators/into ”.” characters. This means you must follow the convention of having directory and file names map directly to the import names.

実際にあなたがsetup.py testを使用するときに、あなたのテストを実行するためにpytestを使用するためには、あなたがあなたのsetup.cfgファイルにエイリアスを登録する必要があることに注意してください(お持ちでない場合はproject/でそれを作成します): \プロジェクト\プロジェクト>のpython setup.pyテスト:

[aliases] 
test = pytest 
+0

私はスクリプトから にそれを変更した後は、私はこのエラー (test_123)Dを得るFOO をインポートマニフェストファイルを読み込むの\ dependency_links.txt インフォproject.eggするtop_level.txt 書き込みdependency_links \-情報をproject.eggするために、トップレベルの名前を書いて 書き込みproject.egg-情報の\ PKG-INFO egg_infoランニング走行試験 'project.egg-info \ SOURCES.txt' マニフェストファイル 'project.egg-info \ SOURCES.txt'を書き込む build_extを実行中 ------------------- -------------------------------------------------- - 0.000sでのラン0テスト OK – user330612

+0

@ user330612:明日見ていきます。 –

+0

@ user330612:私の答えにGood Practicesのリンクをメモしてください。 'pytest'を使ってテストを実行する前に' setup.cfg'ファイルにエイリアスを追加しなければならないという情報があります。 –

関連する問題