2016-06-01 11 views
3

Im Gegensatz zu dieser Frage läuft: Importing modules from a sibling directory for use with py.test ich etwas von meiner App importieren kann, aber es gibt einen Importfehler (sieht aus wie eine zirkuläre Abhängigkeit), die von wirft ' innen‘myapp während der Durchführung des Tests und nicht, wenn myapp allein ausgeführt wird:Import zeigt mit py.test, aber nicht, wenn die App

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

Aber:

$ 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 =============================================================== 

Wie Sie sehen können, ist das Problem nicht die import Anweisung aus der Testdatei. Es ist von "innen" myapp angehoben. Hier

ist die komplette Struktur:

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

myapp.py enthält:

#!/usr/bin/env python3 

from lib.core import base 

base.do_things() 

lib/__ init__.py enthält:

something = "Some dummy string (correct output)" 

base.py enthält:

from lib import something 

def do_things(): 
    print(something) 
    return True 

und test_things enthält:

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() 

Und $PYTHONPATH richtig eingestellt erscheint (so: Py.test No module named * nicht mein Problem beantworten). (Oder, wenn dies nicht richtig ist, wie kann ich es beheben?)

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

kann ich nicht beantworten, was das Problem hier genau ist, aber Messing mit 'sys.path' und' PYTHONPATH' immer ein Rezept für Schwierigkeiten. Ich würde empfehlen, nur das Projekt in einer [virtualenv] (https://virtualenv.pypa.io/en/stable/) Installation oder die Verwendung [Tox] (https://tox.readthedocs.io/en/latest/) und mit voll qualifizierten Importen wie 'from myapp.lib import something'. –

+0

@TheCompiler danke für diese Hinweise. Ich habe es nicht präzisiert, weil es schon ein langer Post war, aber normalerweise ist 'PYTHONPATH' leer (das Problem bleibt genau gleich). Ich mag es auch nicht, mich mit 'sys.path' zu befassen, aber ich habe irgendwo gesehen, dass es keine andere Möglichkeit gibt,' py.text' mit python3 zu verwenden. Also werde ich prüfen, ob virtualenv und/oder tox helfen, den Fall zu lösen (obwohl ich erwarte, dass sie dafür nicht notwendig sind). – zezollo

+0

Wo hast du das gelesen? Ich bin (und ich bin mir sicher, dass unzählige andere) pytest einfach gut mit python3 ohne 'sys.path' shenanigans verwenden. –

Antwort

3

die PYTHONPATH einstellen sollte es tun.

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

(in diesem Beispiel ist es der Pfad/myapp myApp und stellen Sie sicher, haben exportiert PYTHONPATH, nicht nur sie gesetzt).

und von myapp laufen entweder

$ py.test 

oder

$ python3 -m pytest 
1

Ein anderer Weg, dies zu tun, ist eine conftest.py Datei in der obersten Ebene des myapp oder in myapp/tests zu setzen. Wie folgt aus:

$ 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 =============================================================== 
$ 

(und PYTHONPATH ist leer:

$ echo $PYTHONPATH 

$ 

)

Auf diese Weise py.test fügt automatisch myapp zu PYTHONPATH.Dadurch wird vermieden, vergessen PYTHONPATH Export und die Tests von myapp einfacher für andere Entwickler machen (die weder benötigt, um dieses Problem zu lösen).