2013-11-19 2 views
6

Ich habe derzeit ein Problem der Architektur der Anwendungsstruktur und seiner Testinfrastruktur.Organisieren von Tests in Golang-Anwendung und Vermeiden von Import-Zyklen Hölle

Hier ist ein kurzer Überblick über das Layout

<GOROOT>/src/myapp/controllers/ 
<GOROOT>/src/myapp/controllers/account.go 
... 
<GOROOT>/src/myapp/models/ 
<GOROOT>/src/myapp/models/account.go 
<GOROOT>/src/myapp/models/account_test.go 
... 
<GOROOT>/src/myapp/components/ 
<GOROOT>/src/myapp/components/comp1/ 
<GOROOT>/src/myapp/components/comp1/impl.go 
<GOROOT>/src/myapp/components/comp1/impl_test.go 
<GOROOT>/src/myapp/components/ 
... 
<GOROOT>/src/myapp/testutil/ 
<GOROOT>/src/myapp/testutil/database.go 
<GOROOT>/src/myapp/testutil/models.go 
... 

Problem 1

Datei myapp/testutil/models.go einige util Funktionen in den models/*_test.go Tests verwendet wird, enthält. Die util-Funktionen verwenden tatsächlich das Paket myapp/models Datenstrukturen und Funktionen. Daher haben wir einen Import-Zyklus: account_test.go importiert Paket, das wiederum importiert models.

Die einzige hier klare Lösung ist wie test_utils.go auf dem gleichen Paket etwas testutil/models.go direkt in der models Pakete zu halten, die ein bisschen ungeschickt mir scheint. Was würde in solchen Fällen am besten umgehen?

Problem 2

testutil Paket hat einige Initialisierung des comp1 (lassen Sie uns sagen, dass es zu einem 3rd-Party-Service ein Client ist). Wenn wir einen Test comp1/impl_test.go ausführen, wird das testutil Paket importiert, und es importiert comp1 Paket, da es für die Initialisierung der Komponente verantwortlich ist. Gleiche zyklische Importhölle. Die Initialisierung an jeden einzelnen Ort in den Testfällen zu verschieben, erscheint wie eine Duplizierung von Code. Noch für einige elegante Lösungen hier auf der Suche ...

Antwort

8

Problem 1

Wenn package testutils nur von package module während Tests verwendet Utility-Funktionen liefern dann nur die Funktionen in models/testutils_test.go setzen: Jetzt wird diese Nutzenfunktion einbezogen werden wenn die models/*_test.go Tests ausgeführt werden. Kein Importzyklus mehr.

Dies ist Ihre "einzige klare Lösung" und ich kann nichts "ungeschickt" damit sehen.

Problem 2

Import-Zyklus: Das gleiche wie oben.

Initialisierung: Ihre comp1/impl_test.go kann eine func init() bieten so keine Notwendigkeit für doppelten Code.

(Die Standardbibliothek ist eine gute Quelle, wie verschiedene Dinge zu testen. IMHO Code-Duplizierung in Testcode nicht eine der sieben Todsünden ist.)

+0

Leider ist diese „nur klare Lösung“ darf nicht teilen einige Funktionen von models/* _ test.go innerhalb von Controllern/* _ test.go (erstellte Mockup-Strukturen, Fixtures usw.). Oder gibt es einen Weg dazu? In Bezug auf eine Verdoppelung der Test-Code - es misst in LOC: Tests sind auch aktualisiert/refaktoriert (so lange die Software entwickelt) und aktualisieren die gleichen 40-60 Zeilen an 5 verschiedenen Orten ist ein Schmerz. – Oleksandr

+1

@Olx: Vielleicht sollte Ihre gesamte Organisation des Codes neu gedacht werden. Go benötigt nicht jeden Typ in seinem eigenen Paket, also könnten Sie vielleicht mehrere Ihrer Pakete zu einem kombinieren? (Alles ist ein Kompromiss.) Vielleicht Ihr Code, um Mockups, Fixtures usw. zu erstellen.könnte sogar (nicht exportiert) in den normalen Paketen leben. Es wäre Teil der Binärdatei, aber diese paar Bytes sollten kein Problem sein. Und Ihr * _test.go könnte es normalerweise benutzen? – Volker

Verwandte Themen