2017-01-24 2 views
1

Ich habe ein relativ kompliziertes Projekt, das von Gradle verwaltet wird. Die meisten Module sind Java-basiert, daher verwende ich IntelliJ (und nicht PyCharm) als IDE. Das Python-Plugin funktioniert gut für das eine Python-Modul, außer dass Unit-Tests nicht funktionieren.Unittest für Python in Intellij konfigurieren

Die Verzeichnisstruktur ist in etwa wie folgt aus:

project_root 
|- aJavaModule 
| |- ... 
|- anotherJavaModule 
| |- ... 
|- python_module/ 
| |- src/ 
|  |- __init__.py 
|  |- util.py 
|  |- test/ 
|  |- __init__.py 
|  |- util.py 
| ... 

Die test/util.py Datei ist dies:.

import unittest 
from util import util_func 

class TestUtilities(unittest.TestCase): 

    def test_util_func(self): 
     ... 

Es gibt eine spezifische virtuelle Umgebung ist für das Python-Modul einrichten in ausführen Dies ist konfiguriert in der Project Structure -> Facets -> python_module als Python Interpreter. Ich bin zuversichtlich, dass dies funktioniert wie erwartet, denn beim Arbeiten in der IDE ist es richtig zu finden relative Dateien, abhängige Bibliotheken, etc.

In der Tat, wenn ich in test/util.py bin die IDE erkennt die from util import util_func: Ich kann klicken bis zur richtigen, etc.

Wenn ich rechts auf die Testklasse und Create Run/Debug Configuration klicke, kann ich das alles einstellen. In diesem Modal enthält es Add content roots to PYTHONPATH und Add source roots to PYTHONPATH, so dass vermutlich die src und test Verzeichnisse gefunden werden. (Beachten Sie, dass python_module/src als Quellstammverzeichnis in der Modalität Projektstruktur markiert ist.) Ich habe versucht, dieses spezifische Skript als Test auszuwählen, alles im Ordner usw. Ich habe auch versucht, das Verzeichnis test außerhalb des Verzeichnisses src zu verschieben Markieren Sie es als Testverzeichnis. Auch hier kann die IDE die Klassen beim Bearbeiten von Dateien finden, aber wenn ich den Test ausführe, schlägt das fehl.

Insbesondere dann, wenn ich die Tests laufen bekomme ich diese:

Testing started at 5:39 PM ... 
Traceback (most recent call last): 
    File "/Users/nathanielford/Library/Application Support/IntelliJIdea2016.3/python/helpers/pycharm/utrunner.py", line 172, in <module> 
    module = loadSource(a[0]) 
    File "/Users/nathanielford/Library/Application Support/IntelliJIdea2016.3/python/helpers/pycharm/utrunner.py", line 65, in loadSource 
    module = imp.load_source(moduleName, fileName) 
    File "/Users/nathanielford/virtualenvironments/ideenv/lib/python3.5/imp.py", line 172, in load_source 
    module = _load(spec) 
    File "<frozen importlib._bootstrap>", line 693, in _load 
    File "<frozen importlib._bootstrap>", line 673, in _load_unlocked 
    File "<frozen importlib._bootstrap_external>", line 665, in exec_module 
    File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed 
    File "/Users/nathanielford/repos/project_root/python_module/src/tests/util.py", line 2, in <module> 
    from util import util_func 
ImportError: cannot import name 'util_func' 

Process finished with exit code 1 

Was muss ich tun, um die IDE-Test Läufer bekommen die richtige Umgebung und Pfadvariablen zu erkennen? (Schalten Sie einfach auf PyCharm ist keine Option.)

den Systempfad Ausgabe (sys.path) bekomme ich folgendes:

System path=['/Users/nathanielford/repos/project_root/python_module/src/tests', '/Users/nathanielford/repos/project_root/python_module/src', '/Users/nathanielford/repos/project_root/python_module', '/Users/nathanielford/Library/Application Support/IntelliJIdea2016.3/python/helpers/pycharm', '/Users/nathanielford/virtualenvironments/ideenv/lib/python35.zip', '/Users/nathanielford/virtualenvironments/ideenv/lib/python3.5', '/Users/nathanielford/virtualenvironments/ideenv/lib/python3.5/plat-darwin', '/Users/nathanielford/virtualenvironments/ideenv/lib/python3.5/lib-dynload', '/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5', '/opt/local/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin', '/Users/nathanielford/virtualenvironments/ideenv/lib/python3.5/site-packages'] 

Dies scheint darauf hinzudeuten, dass das src Verzeichnis ist in der Tat gefunden werden? Also sollte alles in diesem Verzeichnis verfügbar sein?

+1

Als Debug-Schritt löst ich vor dieser Import-Anweisung einen Import für das Modul sys Hinzufügen versuchen würde, und dann sys.path ausdrucken. Dadurch wird aufgelistet, um welchen Pythonpfad es sich handelt, und Sie können nach Diskrepanzen suchen. Wenn Sie vor dem Import ein "import pdb; pdb.set_trace()" in Ihren Code einfügen, können Sie auch eine Debug-Konsole erstellen, mit der Sie herumstöbern können. (IDK, wenn pdb in intellij unterstützt wird oder nicht) – BretD

+1

Übersehen etwas. Wenn die Datei util.py 'import util' enthält, welches Modul laden Sie?Python fügt das aktuelle Verzeichnis in den Suchpfad ein, sodass es tatsächlich versucht, eine Funktion von sich selbst anstelle des gewünschten Moduls zu importieren. Benennen Sie Ihren Test in util_test.py um und probieren Sie es aus und sehen Sie, ob es funktioniert – BretD

+0

@BretD Ah! Ich habe vergessen, dass ich Python-Dateien mit 'test_' voranstellen muss, weil der Namespace keine Rolle spielt wie in Java. Danke für den Fang! Wenn Sie eine Antwort einreichen wollen, akzeptiere ich sie. –

Antwort

1

Das Problem liegt an Namespaces in Python. Da sowohl Ihr Test als auch die zu testende Datei den Namen "util.py" haben, importiert Python von der ersten, die es im Python-Pfad findet.

Da sich das Testverzeichnis vor dem übergeordneten Verzeichnis in dieser Pfadvariablen befindet, versucht es, aus dem Test selbst zu importieren, für den diese Funktion nicht definiert ist.

Umbenennung einfach den Tests zu „test_util.py“ würde die Namespace-Ausgabe

+0

Danke! Aus Neugier, wissen Sie, ob es eine Möglichkeit gibt, gezielt auf eine Datei für einen Import zu verweisen? Oder müssen Sie immer sicherstellen, dass Ihre Datei nicht dem eines Moduls entspricht, von dem Sie importieren? –

+0

@NathanielFord Python verwendet Pakete, um Namespace-Konflikte zu vermeiden https://docs.python.org/3/tutorial/modules.html#packages So können Sie eine \ __ init \ __. Py-Datei zu einem Verzeichnis hinzufügen und dann dot verwenden Notation für Importe. – BretD