3

アプリを実行していないとき: Importing modules from a sibling directory for use with py.test 私は私のアプリから何かをインポートすることができますが、から提起インポートエラーが(循環依存のように見える) "がありますmyapp「内部だけでmyappを実行するときにテストを実行していない間:はImportErrorはpy.testで現れますが、この質問には異なり

$ python3 myapp/myapp.py 
Some dummy string (correct output) 

しかし:

$ python3 -m pytest                    
================================================================= test session starts ================================================================= 
platform linux -- Python 3.4.3, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 
rootdir: /home/nico/temp/projects_structures/test04/myapp, inifile: 
plugins: cov-2.2.1 
collected 0 items/1 errors 

======================================================================= ERRORS ======================================================================== 
________________________________________________________ ERROR collecting tests/test_things.py ________________________________________________________ 
tests/test_things.py:4: in <module> 
    from myapp.lib.core.base import do_things 
myapp/lib/core/base.py:1: in <module> 
    from lib import something 
E ImportError: No module named 'lib' 
=============================================================== 1 error in 0.05 seconds =============================================================== 

ご覧のとおり、問題はではなく、importというテストファイルの文です。それは '内側から'持ち上げたmyappです。ここで

は完全な構造です:

. 
└── myapp 
    ├── myapp 
    │   ├── __init__.py 
    │   ├── lib 
    │   │   ├── core 
    │   │   │   ├── base.py 
    │   │   │   └── __init__.py 
    │   │   └── __init__.py 
    │   └── myapp.py 
    └── tests 
     └── test_things.py 

myapp.pyは含まれています

#!/usr/bin/env python3 

from lib.core import base 

base.do_things() 

のlib/__ init__.pyが含まれています

something = "Some dummy string (correct output)" 

base.pyは含まれています

from lib import something 

def do_things(): 
    print(something) 
    return True 

とtest_thingsは含まれています(: Py.test No module named * 私の問題に答えていないので、これは)

import unittest 
import sys 
sys.path.insert(0, '..') 
from myapp.lib.core.base import do_things 

class DoThingsTestCase(unittest.TestCase): 

    def test_do_things(self): 
     self.assertTrue(do_things()) 

if __name__ == '__main__': 
    unittest.main() 

そして$PYTHONPATHが正しく設定されそうです。 (これが正しくない場合、または、私はそれをどのように修正することができますか?)

$ echo $PYTHONPATH 
/home/nico/temp/projects_structures/test04/myapp/myapp 
+0

ここでの問題は正確に答えることはできませんが、 'sys.path'と' PYTHONPATH'をつぶすことは常にトラブルのレシピです。私はあなたのプロジェクトを[virtualenv](https://virtualenv.pypa.io/en/stable/)にインストールするか、[tox](https://tox.readthedocs.io/en/latest/)を使ってインストールすることをお勧めします。 'myapp.lib import something'のような完全修飾インポートを使用しています。 –

+0

@TheCompilerはこれらのヒントについて感謝します。私はそれがすでに長いポストだったので、正確ではなかったが、通常は 'PYTHONPATH'は空です(問題はまったく同じです)。私は 'sys.path'を使いこなすのは好きではありませんが、python3で' py.text'を使う方法は他にありません。だから、virtualenvやtoxがその問題を解決するのに役立つかどうかをチェックする(私はそれらが必要ではないと思うだろうが)。 – zezollo

+0

どこを読んだのですか?私はPython3でpytestを使って 'sys.path'を何もせずにpytestを使っています(そして無数の人がいると確信しています)。 –

答えて

3

トリックを行う必要がありますPYTHONPATHを設定します。

$ export PYTHONPATH=<ABSOLUTE PATH TO TOPMOST myapp dir> 

(この例では、/ myappのをmyappのためのパスであり、あなたはがそれを設定するだけでなく、PYTHONPATHを輸出してきたことを確認)。

及びこれを行うための別の方法はmyapp、またはmyapp/tests中のトップレベルにconftest.pyファイルを置くことです

$ py.test 

または

$ python3 -m pytest 
1

いずれかmyappの実行から。このように:

$ pwd 
/home/nico/temp/projects_structures/test04/myapp/tests 
$ touch conftest.py 
$ cd .. 
$ py.test 
================================================================= test session starts ================================================================= 
platform linux2 -- Python 2.7.6, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 
rootdir: /home/nico/temp/projects_structures/test04/myapp, inifile: 
collected 1 items 

tests/test_things.py . 

============================================================== 1 passed in 0.05 seconds =============================================================== 
$ 

(とPYTHONPATHは空です:

$ echo $PYTHONPATH 

$ 

この方法で、py.testは自動的にPYTHONPATHmyappを追加します。これにより、PYTHONPATHのエクスポートを忘れることがなくなり、この問題を解決する必要のない他の開発者にとっては、myappのテストが容易になります。

関連する問題