2015-02-22 22 views
5

Das ist mein Projekt ein:Python Unittest Import Probleme

my_project 
    ./my_project 
     ./__init__.py 
     ./foo 
       ./__init__.py 
       ./bar.py 
     ./tests 
      ./__init__.py 
      ./test_bar.py 

Innen test_bar.py ich die folgende Import-Anweisung haben: from foo import bar

Allerdings, wenn ich python /my_project/tests/test_bar.py betreibe ich diesen Fehler:

ImportError: No module named foo.

Irgendwelche Ideen, wie Sie das beheben können?

+0

Try 'import sys; sys.path.append ('..') 'in' test_bar.py'. Eine bessere Lösung wäre es, 'sys.path' basierend auf dem absoluten Pfad von my_project zu modifizieren. – linuxfan

+0

Ich möchte den Code ideal so organisieren, dass ich das nicht tun muss .... Was wäre eine bessere Möglichkeit, den Code zu organisieren? –

+0

Es gibt keine Notwendigkeit, sich mit 'sys.path' herumzuärgern; Das ist der falsche Weg. Hier ist ein Beispiel: http://StackOverflow.com/Questions/7685483 – FMc

Antwort

8

Denken Sie, was auf Ihrem PYTHONPATH ist. Das Toplevel-Paket für Ihr Projekt ist my_project, so dass der Beginn eines beliebigen Imports für etwas in Ihrem Projekt sein muss.

from my_project.foo import bar 

Sie könnten auch einen relativen Import verwenden, obwohl dies nicht so klar ist, und brechen würden, wenn Sie jemals die relative Position des Moduls geändert Sie von diesem Import verrichten.

from ..foo import bar 

Idealerweise ist der test Ordner ist kein Paket überhaupt, und ist nicht Teil des Anwendungspakets. Siehe pytests Seite auf good practices. Dies erfordert, dass Sie ein setup.py zu Ihrem Paket hinzufügen und es in Ihrem virtualenv im Entwicklungsmodus installieren.

pip install -e . 

Sie die Tests nicht direkt an einer Datei in Ihrer Anwendung durch den Hinweis. Nachdem Sie Ihr Projekt korrekt strukturiert/installiert haben, verwenden Sie den Erkennungsmechanismus für jedes Framework, mit dem Sie die Tests für Sie ausführen. Zum Beispiel mit pytest weist nur im Testordner:

pytest tests 

Oder für den Einbau-Modul Unittest:

python -m unittest discover -s tests 
+0

Ja, ich habe versucht '' from my_project.foo import bar' zu machen. Das Problem ist, dass dies beim Versuch, 'python my_project/tests/test_bar.py' auszuführen, abbricht. Allerdings kann ich es so ausführen:' python - m my_project.tests.test_bar' –

+0

@AtulBhatia Führen Sie Ihre Tests nicht direkt so aus.Verwenden Sie die Discovery, die in das von Ihnen verwendete Testframework integriert ist. Dies entspricht der Struktur, die ich mit dem * Rest meiner Antwort * beschrieben habe. . – davidism

1

können Sie relativ Importe verwenden:

from ..foo import bar 

https://docs.python.org/2/whatsnew/2.5.html#pep-328-absolute-and-relative-imports

, aber ich denke auch, dass durch installing Ihr Projekt in Venv absolute Pfade mit besserer Weg ist.

+0

Ich möchte den Code idealerweise so organisieren, dass ich das nicht tun muss ein besserer Weg, um den Code zu organisieren? –

+0

@AtulBhatia Sie können abhängigen Code auf äußere Ebene verschieben oder vielleicht foo oder das ganze Projekt als separate App mit setup.py – ndpu

0
import sys 
sys.path.append('/path/to/my_project/') 

Jetzt können Sie

importieren über
from foo import bar 
+0

machen Es gibt absolut keinen Grund, dass Sie mit dem Pfad in diesem Fall werden – davidism