Die sehr verbreitete Verzeichnisstruktur selbst für ein einfaches Python-Modul scheint darin zu bestehen, die Komponententests in ein eigenes test
Verzeichnis zu unterteilen:
new_project/
antigravity/
antigravity.py
test/
test_antigravity.py
setup.py
etc.
Sehen Sie sich zum Beispiel dieses Python-Projekt-Howto an .
Meine Frage ist einfach: Wie werden die Tests normalerweise ausgeführt? Ich vermute, dass dies für alle außer mir offensichtlich ist, aber Sie können nicht einfach vom Testverzeichnis python test_antigravity.py
aus ausführen, da dies import antigravity
fehlschlagen wird, da sich das Modul nicht auf dem Pfad befindet.
Ich weiß, dass ich PYTHONPATH und andere Tricks im Zusammenhang mit Suchpfaden ändern könnte, aber ich kann nicht glauben, dass dies der einfachste Weg ist - es ist in Ordnung, wenn Sie der Entwickler sind, aber nicht realistisch, von Ihren Benutzern zu erwarten, dass sie sie verwenden, wenn sie nur die Tests überprüfen möchten Vorbeigehen.
Die andere Alternative besteht darin, die Testdatei nur in das andere Verzeichnis zu kopieren, aber es scheint ein bisschen dumm zu sein und es fehlt der Sinn, sie zunächst in einem separaten Verzeichnis zu haben.
Wenn Sie also gerade die Quelle in mein neues Projekt heruntergeladen hätten, wie würden Sie die Komponententests durchführen? Ich würde eine Antwort bevorzugen, mit der ich meinen Benutzern sagen könnte: "Um die Komponententests auszuführen, machen Sie X."
quelle
unittest
Befehlszeilenschnittstelle, wie in meiner Antwort unten beschrieben, damit Sie das Verzeichnis nicht zum Pfad hinzufügen müssen.Antworten:
Die beste Lösung ist meiner Meinung nach, die
unittest
Befehlszeilenschnittstelle zu verwenden, die das Verzeichnis zu dem hinzufügt,sys.path
damit Sie es nicht müssen (in derTestLoader
Klasse erledigt ).Zum Beispiel für eine Verzeichnisstruktur wie diese:
Sie können einfach ausführen:
Für eine Verzeichnisstruktur wie Ihre:
Und in den Testmodulen innerhalb des
test
Pakets können Sie dasantigravity
Paket und seine Module wie gewohnt importieren :Ausführen eines einzelnen Testmoduls:
So führen Sie ein einzelnes Testmodul aus
test_antigravity.py
:Referenzieren Sie das Testmodul genauso wie Sie es importieren.
Ausführen eines einzelnen Testfalls oder einer Testmethode:
Sie können auch eine einzelne
TestCase
oder eine einzelne Testmethode ausführen :Alle Tests ausführen:
Sie können auch mit Test Entdeckung , die alle Tests für Sie entdecken und ausführen können , müssen sie benannt Module oder Pakete sein
test*.py
(kann mit der geändert werden-p, --pattern
flag):Dadurch werden alle
test*.py
Module imtest
Paket ausgeführt.quelle
python -m unittest discover
findet Tests imtest
Verzeichnis und führt sie aus, wenn sie benannt sindtest*.py
. Wenn Sie das Unterverzeichnis benannt habentests
, verwenden Siepython -m unittest discover -s tests
, und wenn Sie die Testdateien benannt habenantigravity_test.py
, verwenden Siepython -m unittest discover -s tests -p '*test.py'
Dateinamen können Unterstriche, aber keine Bindestriche verwenden.ImportError: No module named 'test.test_antigravity'
aufgrund eines Konflikts mit dem Test-Submodul der unittest-Bibliothek fehl . Möglicherweise kann ein Experte den Namen des Antwort-Unterverzeichnisses bestätigen und in "Tests" (Plural) ändern.test_antigravity.py
wirft immer noch einen Importfehler für beideimport antigravity
undfrom antigravity import antigravity
auch. Ich habe beide__init_.py
Dateien und rufepython3 -m unittest discover
aus demnew project
Verzeichnis an. Was könnte sonst noch falsch sein?test/__init__.py
ist hier entscheidend, auch wenn leertest
Besonderes ist ... aber nur für den Datensatz ist es nicht. : Ppython -m unittest discover
funktioniert mit Testdateientests/
genauso gut wietest/
.Die einfachste Lösung für Ihre Benutzer besteht darin, ein ausführbares Skript (
runtests.py
oder ein solches) bereitzustellen, das die erforderliche Testumgebung bootet und bei Bedarf Ihr Stammprojektverzeichnissys.path
vorübergehend hinzufügt . Dies erfordert nicht, dass Benutzer Umgebungsvariablen festlegen. So etwas funktioniert in einem Bootstrap-Skript einwandfrei:Dann können Ihre Anweisungen an Ihre Benutzer so einfach wie "
python runtests.py
" sein.Wenn der Pfad, den Sie wirklich benötigen, wirklich ist
os.path.dirname(__file__)
, müssen Sie ihn natürlich überhaupt nicht hinzufügensys.path
. Python setzt das Verzeichnis des aktuell ausgeführten Skripts immer an den Anfang vonsys.path
. Abhängig von Ihrer Verzeichnisstruktur istruntests.py
es möglicherweise alles, was Sie benötigen , um Ihr Verzeichnis an der richtigen Stelle zu finden.Auch das Unittest - Modul in Python 2.7+ (die als zurückportiert wird unittest2 für Python 2.6 und früher) hat nun Test Entdeckung eingebaut, so Nase ist nicht mehr erforderlich , wenn Sie automatisierte Test Entdeckung wollen: Ihre Benutzeranweisungen können so einfach wie
python -m unittest discover
.quelle
python -m pdb tests\test_antigravity.py
. In pdb habe ich ausgeführtsys.path.insert(0, "antigravity")
, wodurch die import-Anweisung aufgelöst werden konnte, als würde ich das Modul ausführen .Im Allgemeinen erstelle ich im Projektverzeichnis ein Skript zum Ausführen von Tests (das sowohl für das Quellverzeichnis als auch für das Quellverzeichnis gilt
test
), das meine Suite "Alle Tests" lädt. Dies ist normalerweise Boilerplate-Code, sodass ich ihn von Projekt zu Projekt wiederverwenden kann.run_tests.py:
test / all_tests.py (von Wie führe ich alle Python- Komponententests in einem Verzeichnis aus? )
Mit diesem Setup können Sie in der Tat nur
include antigravity
in Ihren Testmodulen. Der Nachteil ist, dass Sie mehr Support-Code benötigen, um einen bestimmten Test auszuführen ... Ich führe sie jedes Mal aus.quelle
run tests
Skript im Projektverzeichnis und fand einen viel saubereren Weg , dies zu tun. Sehr empfehlenswert.Aus dem Artikel, den Sie verlinkt haben:
Vielleicht sollten Sie sich die Nase ansehen, wie es nahelegt?
quelle
Ich hatte das gleiche Problem mit einem separaten Ordner für Komponententests. Aus den genannten Vorschlägen füge ich den absoluten Source - Pfad zu
sys.path
.Der Vorteil der folgenden Lösung besteht darin, dass die Datei ausgeführt werden kann,
test/test_yourmodule.py
ohne zunächst in das Testverzeichnis zu wechseln:quelle
Wenn Sie "python setup.py Develop" ausführen, befindet sich das Paket im Pfad. Möglicherweise möchten Sie dies jedoch nicht tun, da Sie Ihre Systempython- Installation infizieren könnten. Aus diesem Grund gibt es Tools wie virtualenv und buildout .
quelle
Lösung / Beispiel für Python unittest Modul
Bei folgender Projektstruktur:
Sie können Ihr Projekt aus dem Stammverzeichnis ausführen, mit
python project_name
dem aufgerufen wirdProjectName/project_name/__main__.py
.Um Ihre Tests
python test
effektiv auszuführenProjectName/test/__main__.py
, müssen Sie Folgendes tun:1) Verwandeln Sie Ihr
test/models
Verzeichnis in ein Paket, indem Sie eine__init__.py
Datei hinzufügen . Dadurch können Sie auf die Testfälle im Unterverzeichnis über das übergeordnetetest
Verzeichnis zugreifen .2) Ändern Sie Ihren Systempfad so
test/__main__.py
, dass er dasproject_name
Verzeichnis enthält.Jetzt können Sie erfolgreich Dinge aus
project_name
Ihren Tests importieren .quelle
Verwenden
setup.py develop
Sie diese Option , um Ihr Arbeitsverzeichnis Teil der installierten Python-Umgebung zu machen, und führen Sie dann die Tests aus.quelle
invalid command 'develop'
und diese Option wird nicht erwähnt, wenn ich danach fragesetup.py --help-commands
. Muss es etwas ansetup.py
sich geben, damit dies funktioniert?import setuptools
in meinersetup.py
Datei vermisst habe . Aber ich denke, das zeigt, dass dies für die Module anderer Leute nicht immer funktioniert.pip install -e .
Dadurch wird das Paket ebenfalls zur Python-Umgebung hinzugefügt, ohne die Quelle zu kopieren, sodass Sie es dort weiter bearbeiten können, wo es liegt.pip install -e .
ist genau das Gleiche wiepython setup.py develop
, essetup.py
passt nur dazu, Setuptools zu verwenden, auch wenn dies nicht der Fall ist, also funktioniert es so oder so.Wenn Sie VS-Code verwenden und sich Ihre Tests auf derselben Ebene wie Ihr Projekt befinden, funktioniert das Ausführen und Debuggen Ihres Codes nicht sofort. Sie können Ihre Datei launch.json ändern:
Die Schlüsselzeile hier ist envFile
Fügen Sie im Stammverzeichnis Ihres Projekts die ENV-Datei hinzu
Fügen Sie innerhalb Ihrer .env-Datei einen Pfad zum Stammverzeichnis Ihres Projekts hinzu. Dies wird vorübergehend hinzugefügt
Wenn Sie den Pfad zu Ihrem Projekt eingeben, können Sie Debug-Unit-Tests aus VS Code verwenden
quelle
Ich habe festgestellt, dass Importe ohne Änderungen korrekt funktionieren, wenn Sie die unittest-Befehlszeilenschnittstelle von Ihrem "src" -Verzeichnis aus ausführen.
Wenn Sie dies in eine Batchdatei in Ihrem Projektverzeichnis einfügen möchten, können Sie dies tun:
quelle
Ich habe seit langer Zeit das gleiche Problem. Was ich kürzlich gewählt habe, ist die folgende Verzeichnisstruktur:
und im
__init__.py
Skript des Testordners schreibe ich Folgendes:Super wichtig für die Freigabe des Projekts ist das Makefile, da es die ordnungsgemäße Ausführung der Skripte erzwingt. Hier ist der Befehl, den ich in das Makefile eingefügt habe:
Das Makefile ist nicht nur wegen des ausgeführten Befehls wichtig, sondern auch, weil es von dort aus ausgeführt wird . Wenn Sie in Tests cd und tun würden
python -m unittest discover .
, würde es nicht funktionieren, weil der init ausführen Skript in unit_tests os.getcwd () aufruft, das dann auf den falschen absoluten Pfad verweist (der an sys.path angehängt wird und Sie fehlen würden Ihr Quellordner). Die Skripte würden ausgeführt, da Discovery alle Tests findet, aber sie würden nicht ordnungsgemäß ausgeführt. Das Makefile soll also verhindern, dass Sie sich an dieses Problem erinnern müssen.Ich mag diesen Ansatz wirklich, weil ich meinen src-Ordner, meine Unit-Tests oder meine Umgebungsvariablen nicht berühren muss und alles reibungslos läuft.
Lass es mich wissen, wenn es euch gefällt.
Ich hoffe, das hilft,
quelle
Folgendes ist meine Projektstruktur:
Ich fand es besser, in die setUp () -Methode zu importieren:
quelle
Ich benutze Python 3.6.2
So installieren Sie pytest :
sudo pip install pytest
Ich habe keine Pfadvariable festgelegt und meine Importe schlagen nicht mit derselben "Test" -Projektstruktur fehl.
Ich habe dieses Zeug auskommentiert:
if __name__ == '__main__'
so:test_antigravity.py
quelle
Es ist möglich, einen Wrapper zu verwenden, der ausgewählte oder alle Tests ausführt.
Zum Beispiel:
oder um alle Tests rekursiv auszuführen, verwenden Sie globbing (
tests/**/*.py
) (enable byshopt -s globstar
).Der Wrapper kann grundsätzlich
argparse
die folgenden Argumente analysieren:Laden Sie dann alle Tests:
Fügen Sie sie dann Ihrer Testsuite hinzu (mit
inspect
):und führen Sie sie:
Überprüfen Sie dieses Beispiel für weitere Details.
Siehe auch: Wie werden alle Python-Komponententests in einem Verzeichnis ausgeführt?
quelle
Python 3+
Hinzufügen zu @Pierre
Verwenden Sie die
unittest
Verzeichnisstruktur wie folgt:So führen Sie das Testmodul aus
test_antigravity.py
:Oder eine einzelne
TestCase
Obligatorisch nicht vergessen,
__init__.py
auch wenn leer, sonst funktioniert es nicht.quelle
Sie können nicht ohne Voodoo aus dem übergeordneten Verzeichnis importieren. Hier ist noch eine andere Möglichkeit, die mit mindestens Python 3.6 funktioniert.
Erstellen Sie zunächst eine Datei test / context.py mit folgendem Inhalt:
Führen Sie dann den folgenden Import in die Datei test / test_antigravity.py durch:
Beachten Sie, dass der Grund für diese Try-Except-Klausel der folgende ist
Mit diesem Trick arbeiten beide.
Jetzt können Sie alle Testdateien im Testverzeichnis ausführen mit:
oder führen Sie eine einzelne Testdatei aus mit:
Ok, es ist nicht viel schöner als den Inhalt von context.py in test_antigravity.py zu haben, aber vielleicht ein bisschen. Vorschläge sind willkommen.
quelle
Wenn Ihr Testverzeichnis mehrere Verzeichnisse enthält, müssen Sie jedem Verzeichnis eine
__init__.py
Datei hinzufügen .Um dann jeden Test auf einmal auszuführen, führen Sie Folgendes aus:
Quelle:
python -m unittest -h
quelle
Dieses BASH-Skript führt das Python-Unittest-Testverzeichnis von einer beliebigen Stelle im Dateisystem aus, unabhängig davon, in welchem Arbeitsverzeichnis Sie sich befinden.
Dies ist nützlich, wenn Sie im
./src
oder./example
Arbeitsverzeichnis bleiben und einen schnellen Komponententest benötigen:Es ist keine
test/__init__.py
Datei erforderlich, um den Paket- / Speicheraufwand während der Produktion zu belasten.quelle
Auf diese Weise können Sie die Testskripte von jedem beliebigen Ort aus ausführen, ohne mit Systemvariablen über die Befehlszeile herumzuspielen.
Dadurch wird der Hauptprojektordner zum Python-Pfad hinzugefügt, wobei der Speicherort relativ zum Skript selbst und nicht relativ zum aktuellen Arbeitsverzeichnis gefunden wird.
Fügen Sie das oben in all Ihren Testskripten hinzu. Dadurch wird der Hauptprojektordner zum Systempfad hinzugefügt, sodass alle Modulimporte, die von dort aus funktionieren, jetzt funktionieren. Und es spielt keine Rolle, von wo aus Sie die Tests ausführen.
Sie können die Datei project_path_hack natürlich so ändern, dass sie dem Speicherort Ihres Hauptprojektordners entspricht.
quelle
Wenn Sie nach einer Nur-Befehlszeilenlösung suchen:
Basierend auf der folgenden Verzeichnisstruktur (verallgemeinert mit einem dedizierten Quellverzeichnis):
Windows : (in
new_project
)Siehe diese Frage, wenn Sie diese in einer Batch-for-Schleife verwenden möchten.
Linux : (in
new_project
)Mit diesem Ansatz ist es auch möglich, dem PYTHONPATH bei Bedarf weitere Verzeichnisse hinzuzufügen.
quelle
Sie sollten das Pip-Tool wirklich verwenden.
Verwenden Sie
pip install -e .
diese Option, um Ihr Paket im Entwicklungsmodus zu installieren. Dies ist eine sehr gute Vorgehensweise, die von pytest empfohlen wird (siehe die Dokumentation zu bewährten Vorgehensweisen , in der Sie auch zwei Projektlayouts finden, denen Sie folgen können).quelle
pytest
ist es viel besser, Tests durchzuführen, da die Konsolenausgabe in Farbe mit Stapelverfolgungsinformationen und detaillierten Informationen zu Assertionsfehlern angezeigt wird.