pyunit tests in seperatem package

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

Hi,


Ich verwende Python 2.6.5 und habe folgende Package Struktur:
core/mycoremodule.py
core/submodule1/submodule1.py
core/submodule2
core/tests/main.py
core/tests/submoduletest1.py
core/tests/submoduletest2.py

Im Paket tests werden alle tests über main.py als eine Testsuite gestartet:

Code: Alles auswählen

import unittest
import submoduletest1
import submoduletest2

suite1 = submoduletest1.suite()
suite2 = submoduletest2.suite()
alltests = unittest.TestSuite((suite1, suite2))
runner = unittest.TextTestRunner()
runner.run(alltests)
Damit in submoduletest1.py Module aus übergeordneten Paketen importiert werden können mache ich folgendes:
1.submoduletest1:

Code: Alles auswählen

from core.mycoremodule import CoreModuleClass
from core.submodule1 import SubModuleClass
2.mycoremodule:

Code: Alles auswählen

from core.submodule1 import SubModuleClass
Damit lassen sich die Tests nun erfolgreich aufrufen, wenn man in das Verzeichnis navigiert, in dem das Package core liegt und
python -c "import core.tests.main"
aufruft.

Will ich nun die mycoremodule.py als eigenständiges Programm ausführen, bekomme dabei aber die Fehlermeldung:
ImportError: No module named core.submodule1.SubModuleClass
Um diesen Fehler zu vermeinden kann ich das "core."-Prefix bei den Imports weglassen, aber dann funktionieren die Tests nicht mehr.

Ich habe es schon mit der unittest.main() versucht und damit core/tests/main.py direkt aufzurufen.
Aber Egal was ich probiert habe, konnte ich nur entwerder die Tests oder mein core Modul laufen lassen ohne etwas an den Paketnamen zu ändern.

Ich habe bisher kein Beispiel gefunden, in dem die Pakete ebenso organisiert waren, also wende ich mich nun an euch. Bitte helft mir meine Paket Imports so zu organisieren, dass ich sowohl die Testsuite als auch mein CoreModul laufen lassen kann. Die Tests sollen wie gesagt in dem jetzigen Paket bleiben.


MfG,
Boa
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Fehlen dir da die "__init__.py" dateien, um aus den Ordnern Packages zu machen?
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

b.esser-wisser hat geschrieben:Fehlen dir da die "__init__.py" dateien, um aus den Ordnern Packages zu machen?
Die leeren __init__.py Dateien befinden sich in allen Paketen. Daran sollte es also nicht liegen. Ich probier Mal das kleine Beispiel, das ich gepostet habe soweit zu vervollständigen, dass es läuft und wenn ich dann immer noch nicht verstehe, was ich falsch mache poste ich es.
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

Ich habe mein ursprüngliches Problem wiederhergestellt, also die erste Stelle, an der ich mit meinem Verständnis gescheitert bin. Ab dort habe ich dann nur noch herumprobiert und keine befriedigende Lösung gefunden:

mycoremodule.py

Code: Alles auswählen

import submodule1
Dieses Skript zeigt, wie ich Module im selben Verzeichnis importieren kann. import submodule1.submodule1 ginge auch, import core.submodule1 nicht, da der Interpreter das aktuelle Verzeichnis anscheinend nicht als Paket erkennt, obwohl eine __init__.py darin liegt.
Nun kann ich aber in submodule1.py keine Module importieren, die auf der selben Ebene in einem anderen Package liegen oder eine Ebene darunter.
Das ist aber wünschenswert, falls submodule1.py ein ausführbarer Test ist. Denn dann will ich Module aus anderen Paketen testen und muss diese vorher importieren.
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Dein 'python -c "import blabla"' finde ich komisch, geht es nicht besser/einfacher/logischer/etc. wenn du einfach dein Testsscript ausführst ('python /PFAD/core/tests/main.py') ?
... oder, wenn du von dem Pfad weg willst und dein core-Package im 'sys.path' liegt, mit 'python -m core.tests.main'.
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

Ich kehre deinen Post Mal um, damit das wichtigste zuerst kommt:
b.esser-wisser hat geschrieben:... oder, wenn du von dem Pfad weg willst und dein core-Package im 'sys.path' liegt, mit 'python -m core.tests.main'.
Also im sys.path scheint das Package nicht zu liegen. Aber das -m Flag ist genau das wonach ich gesucht habe. Damit erkennen sowohl die Module in tests als auch die Module in core Referenzen der Art import core.ANYTHING.
Tag gerettet -> Vielen Dank :)
b.esser-wisser hat geschrieben:Dein 'python -c "import blabla"' finde ich komisch, geht es nicht besser/einfacher/logischer/etc. wenn du einfach dein Testsscript ausführst ('python /PFAD/core/tests/main.py') ?
Das geht nicht, weil main.py Module importiert, die in core liegen. Zudem importiert das Modul in core wiederum Module aus den Subpaketen. Das Problem habe ich im Post vom "Sa Jan 29, 2011 19:34" nachgestellt. Mit 'python PFAD' kann man das core Modul ausführen, wenn die imports nicht mit core anfangen. Und das Modul im Subpaket kann man mit python -c "import core.blubb.main" ausführen, da das Submodul dann imports der Form core.blubb erkennt. Je nachdem wie die imports aussehen geht das eine oder das andere.
Ich habe mir sys.path angesehen und mich gewundert, dass das working directory nicht drin steht. Das erste Item lautet ''
Vielleicht liegt es daran. Da ich nicht jedes Mal wenn ich das Modul verschiebe sys.path verändern oder die entsprechende Umgebungsvariable anpassen will sehe ich davon ab das auszuprobieren oder ist das so üblich?

Vielen Dank noch Mal b.esser-wisser,
Boa
syntor
User
Beiträge: 88
Registriert: Donnerstag 2. Dezember 2010, 03:56

Der leere String IST das "working directory".

Ich würde dir ja einen gänzlich anderen Ansatz ans Herz legen:
Automatic test discovery, wie es z.B. nose oder unittest2 bieten.

Zusätzlich dazu:
  • virtualenv
  • setuptool's develop
Das zweite hilft dir dabei, dir über das aktuelle Verzeichnis keine Sorgen mehr machen zu müssen, da dein Paket nun von überall her gefunden wird.
Danach ist Testen so einfach, wie `nosetests` bzw `nosetests --with-coverage` wenn du coverage installiert hast.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Ich habe noch nen besseren Vorschlag: tox nutzen :)

Da werden die nötigen virtualenvs für dich automatisch und transparent erstellt. es gibt eine tox.ini, in der du festlegst, was beim Aufruf von "tox" passieren soll. Mit tox kannst du auch ganz leicht mehrere Python-Versionen testen. Einfach in die Doku schauen, die enthält auch sehr viele Beispiele.
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Wenn du nicht auf ein anderes testframework umsteigen willst, musst du dafür sorgen, dass 'core' als Package gefunden und erkannt wird, indem der Ordner, in dem 'core' liegt in 'sys.path' aufgenommen wird:
  1. Dein Testscript ändert 'sys.path' (hab ich hier unter windows mit pygtk und cairo so gemacht, damit die dlls gefunden werden).
  2. Du nimmst den Pfad zu 'core' in die Umgebungsvariable 'PYTHONPATH' auf (das werden wohl auch virtualenv und co. machen)
  3. Du setzt eine '.pth' datei mit dem Pfad zu 'core' in ein Verzeichnis in 'sys.path' (in 'site-packages' liegen z.B. welche von easy_install, falls du das nutzt)
  4. Du hängst den Pfad an die Umgebungsvariable PATH an (ist oft die Universal-/Holzhammer-lösung, kann auf längere Sicht zu Problemen führen
hth, Jörg

ps.: warum ist ".." nicht in Pythons Suchpfad?
Wahrscheinlich, weil das in den meisten Fällen nicht sehr hilfreich ist (und wenn symbolische links bzw. Junctions ins Spiel kommen, gibt es mehrere 'übergeordnete' Verzeichnisse, und '..' ist dann das falsche).
Antworten