Gibt es eine bewährte Methode zur Trennung von Komponententests und Integrationstests in GoLang (testify)? Ich habe eine Mischung aus Komponententests (die nicht auf externen Ressourcen beruhen und daher sehr schnell ausgeführt werden) und Integrationstests (die auf externen Ressourcen basieren und daher langsamer ausgeführt werden). Ich möchte also steuern können, ob die Integrationstests eingeschlossen werden sollen oder nicht, wenn ich sage go test
.
Die einfachste Technik scheint darin zu bestehen, ein Integrationsflag in main zu definieren:
var runIntegrationTests = flag.Bool("integration", false
, "Run the integration tests (in addition to the unit tests)")
Und dann, um jedem Integrationstest eine if-Anweisung hinzuzufügen:
if !*runIntegrationTests {
this.T().Skip("To run this test, use: go test -integration")
}
Ist das das Beste, was ich tun kann? Ich habe in der Zeugnisdokumentation nach einer Namenskonvention oder etwas gesucht, das dies für mich bewirkt, aber nichts gefunden. Vermisse ich etwas
quelle
var integration = flag.Bool("integration", true, "Enable integration testing.")
die Variable als außerhalb einer Funktion definieren, wird die Variable im PaketbereichAntworten:
@ Ainar-G schlägt mehrere großartige Muster vor, um Tests zu trennen.
Diese Go-Vorgehensweise von SoundCloud empfiehlt die Verwendung von Build-Tags ( beschrieben im Abschnitt "Build-Einschränkungen" des Build-Pakets ), um auszuwählen, welche Tests ausgeführt werden sollen:
Als ähnliche Option können Integrationstests auch standardmäßig mithilfe einer Erstellungsbedingung ausgeführt
// +build !unit
und bei Bedarf durch Ausführen deaktiviert werdengo test -tags=unit
.@ adamc Kommentare:
Für alle anderen Personen, die versuchen, Build-Tags zu verwenden, ist es wichtig, dass der
// +build test
Kommentar die erste Zeile in Ihrer Datei ist und dass Sie nach dem Kommentar eine leere Zeile einfügen. Andernfalls-tags
ignoriert der Befehl die Anweisung.Außerdem kann das im Build-Kommentar verwendete Tag keinen Bindestrich enthalten, obwohl Unterstriche zulässig sind. Zum Beispiel
// +build unit-tests
wird nicht funktionieren, während// +build unit_tests
wird.quelle
// + build unit
in Unit-Tests festgelegt und -tag Unit verwenden, um die Tests// +build
Testkommentar die erste Zeile in Ihrer Datei ist und dass Sie nach dem Kommentar eine leere Zeile einfügen. Andernfalls-tags
ignoriert der Befehl die Anweisung. Außerdem kann das im Build-Kommentar verwendete Tag keinen Bindestrich enthalten, obwohl Unterstriche zulässig sind. Zum Beispiel// +build unit-tests
wird nicht funktionieren, während// +build unit_tests
wirdgo test -tags=integration ./...
funktioniert nicht, es ignoriert das TagUm näher auf meinem Kommentar zu @ Ainar-G ausgezeichnete Antwort, im vergangenen Jahr habe ich die Kombination der Verwendung
-short
mitIntegration
Namenskonvention das Beste aus beiden Welten zu erreichen.Unit und Integration testen die Harmonie in derselben Datei
Build - Flags hat mich gezwungen , die zuvor mehrere Dateien zu haben (
services_test.go
,services_integration_test.go
usw.).Nehmen Sie stattdessen das folgende Beispiel, in dem die ersten beiden Unit-Tests sind und ich am Ende einen Integrationstest habe:
Beachten Sie, dass der letzte Test die Konvention hat:
Integration
im Testnamen.-short
Flag-Direktive ausgeführt wird.Grundsätzlich lautet die Spezifikation: "Schreiben Sie alle Tests normal. Wenn es sich um Langzeittests oder Integrationstests handelt, befolgen Sie diese Namenskonvention und prüfen Sie, ob Sie
-short
Ihren Kollegen gegenüber nett sind."Nur Unit-Tests ausführen:
Dies bietet Ihnen eine schöne Reihe von Nachrichten wie:
Führen Sie nur Integrationstests aus:
Dies führt nur die Integrationstests aus. Nützlich für die Rauchprüfung von Kanarienvögeln in der Produktion.
Offensichtlich ist der Nachteil dieses Ansatzes, dass, wenn jemand
go test
ohne das-short
Flag ausgeführt wird, standardmäßig alle Tests ausgeführt werden - Einheiten- und Integrationstests.Wenn Ihr Projekt groß genug ist, um Unit- und Integrationstests durchzuführen, verwenden Sie in der Realität höchstwahrscheinlich eine,
Makefile
in der Sie einfache Anweisungen verwendengo test -short
können. Oder legen Sie es einfach in IhreREADME.md
Datei und nennen Sie es den Tag.quelle
import
mein Paket testen und dagegen testen kann, was mir letztendlich zeigt, wie meine API für andere aussieht. Ich folge dann jeder verbleibenden Logik, die als interne Testpaketnamen behandelt werden muss.package services
weiß, enthält hier ein Integrationstest. Um die API für das Paket als Blackbox zu testen, sollten wir es anders benennen, damit wirpackage services_integration_test
nicht mit internen Strukturen arbeiten können. Daher sollte das Paket für Komponententests (Zugriff auf Interna) benannt werdenpackage services
. Ist es so?Ich sehe drei mögliche Lösungen. Der erste besteht darin, den Kurzmodus für Komponententests zu verwenden. Sie würden also
go test -short
mit Komponententests und demselben verwenden, jedoch ohne das-short
Flag, um auch Ihre Integrationstests auszuführen. Die Standardbibliothek verwendet den Kurzmodus, um entweder lange laufende Tests zu überspringen oder sie durch die Bereitstellung einfacherer Daten schneller auszuführen.Die zweite besteht darin, eine Konvention zu verwenden und Ihre Tests entweder
TestUnitFoo
oder aufzurufenTestIntegrationFoo
und dann das-run
Testflag zu verwenden, um anzugeben, welche Tests ausgeführt werden sollen. Sie würden alsogo test -run 'Unit'
für Unit-Tests undgo test -run 'Integration'
für Integrationstests verwenden.Die dritte Option besteht darin, eine Umgebungsvariable zu verwenden und sie in Ihrem Test-Setup mit abzurufen
os.Getenv
. Dann würden Sie einfachgo test
für Unit-Tests undFOO_TEST_INTEGRATION=true go test
für Integrationstests verwenden.Ich persönlich würde das vorziehen
-short
Lösung , da sie einfacher ist und in der Standardbibliothek verwendet wird. Es scheint also eine de facto Möglichkeit zu sein, lang laufende Tests zu trennen / zu vereinfachen. Die-run
undos.Getenv
-Lösungen bieten jedoch mehr Flexibilität (auch Vorsicht ist geboten, da es sich um reguläre Ausdrücke handelt-run
).quelle
Tester-Go
), die IDEs (Atom, Sublime usw.) gemeinsam sind, die integrierte Option haben-short
, zusammen mit-coverage
und anderen mit Flag ausgeführt zu werden . Daher verwende ich eine Kombination aus beiden Integrationen im Testnamen undif testing.Short()
Überprüfungen innerhalb dieser Tests. es ermöglicht mir, das Beste aus beiden Welten zu haben:-short
innerhalb von IDEs ausführen und explizit nur Integrationstests mitgo test -run "Integration"
Ich habe kürzlich versucht, eine Lösung dafür zu finden. Das waren meine Kriterien:
Die oben genannten Lösungen (benutzerdefiniertes Flag, benutzerdefiniertes Build-Tag, Umgebungsvariablen) erfüllten nicht alle oben genannten Kriterien. Nach einigem Graben und Spielen kam ich auf diese Lösung:
Die Implementierung ist unkompliziert und minimal. Es erfordert zwar eine einfache Konvention für Tests, ist aber weniger fehleranfällig. Eine weitere Verbesserung könnte darin bestehen, den Code in eine Hilfsfunktion zu exportieren.
Verwendung
Führen Sie Integrationstests nur für alle Pakete in einem Projekt aus:
Führen Sie alle Tests aus ( regulär und Integration):
Führen Sie nur regelmäßige Tests durch:
Diese Lösung funktioniert gut ohne Werkzeuge, aber ein Makefile oder einige Aliase können es dem Benutzer leichter machen. Es kann auch problemlos in jede IDE integriert werden, die das Ausführen von Go-Tests unterstützt.
Das vollständige Beispiel finden Sie hier: https://github.com/sagikazarmark/modern-go-application
quelle