Wie kann ich eine gemeinsame Testsuite für mehrere Pakete erhalten?

8

Wenn ich eine Schnittstelle schreibe, ist es oft praktisch, meine Tests im selben Paket wie die Schnittstelle zu definieren und dann mehrere Pakete zu definieren, die die Schnittstelle implementieren, z. B.

%Vor%

Gibt es eine einfache Möglichkeit, dieselbe Testsuite (in diesem Fall in Paket / * _ test.go) in den Unterpaketen auszuführen?

Die beste Lösung, die ich bisher gefunden habe, ist ein Testpaket hinzuzufügen:

%Vor%

Was implementiert die Testsuite und einen Test in jeder Implementierung, um die Tests auszuführen, aber dies hat zwei Nachteile:

1) Die Tests in Paket / Tests sind nicht in _test.go Dateien, und am Ende werden Teil der eigentlichen Bibliothek, dokumentiert von godoc, etc.

2) Die Tests in Paketen / Tests werden von einem benutzerdefinierten Test-Runner ausgeführt, der im Grunde alle Funktionen von 'go test' duplizieren muss, um nach go-Tests zu suchen und sie auszuführen.

Scheint wie eine ziemlich klebrige Lösung.

Gibt es einen besseren Weg, dies zu tun?

    
Doug 09.04.2013, 09:07
quelle

3 Antworten

7

Ich mag die Idee, eine separate Testbibliothek zu verwenden, nicht wirklich. Wenn Sie über eine Schnittstelle verfügen und für jede Schnittstelle generische Tests haben, möchten möglicherweise auch andere Personen, die diese Schnittstelle implementieren, diese Tests verwenden.

Sie könnten ein Paket "package/test" erstellen, das eine Funktion

enthält %Vor%

Beachten Sie, dass die Signatur von TestInterface nicht mit der von go test erwarteten übereinstimmt. Jetzt fügen Sie für jedes Paket package/impl/x eine Datei generic_test.go hinzu:

%Vor%

Dabei ist New() die Konstruktorfunktion Ihrer Implementierung. Der Vorteil bei diesem Schema ist, dass

  1. Ihre Tests sind wiederverwendbar für jeden, der Ihre Schnittstelle implementiert, auch von anderen Paketen
  2. Es ist sofort offensichtlich, dass Sie die generische Testsuite
  3. ausführen
  4. Die Testfälle sind wo die Implementierung ist und nicht an einem anderen, obskuren Ort
  5. Der Code kann leicht angepasst werden, wenn eine Implementierung spezielle Initialisierung oder ähnliches benötigt
  6. Es ist go test kompatibel (großes Plus!)

Natürlich benötigen Sie in manchen Fällen eine kompliziertere TestInterface -Funktion, aber das ist die Grundidee.

    
fuz 09.04.2013, 15:14
quelle
1

Wenn Sie einen Codeabschnitt für die Wiederverwendung durch verschiedene Pakete freigeben, dann ist dies definitionsgemäß eine Bibliothek. Auch wenn es nur zum Testen von * _test.go-Dateien verwendet wird. Es unterscheidet sich nicht vom Importieren von "Testen" von "fmt" in der Datei _test.go. Und die API von godoc dokumentiert zu haben ist ein Plus, nicht minus IMHO.

    
zzzz 09.04.2013 09:12
quelle
1

Vielleicht wird hier ein bisschen was durcheinander gebracht: Wenn das Paket a nur eine Schnittstelle definiert, gibt es keinen Code Test als Schnittstellen in Go sind Implementierung frei.

Ich nehme also die Methoden in Ihrer Schnittstelle in Paket a an Einschränkungen haben. Z.B. in

%Vor%

Ihr Vertrag geht davon aus, dass "Müde" wahr zurückgibt, wenn mehr als 500 Schritte wurden ausgeführt (und ansonsten falsch) und Ihr Testcode überprüft diese Abhängigkeiten (oder Annahme, Verträge, Invarianten, was auch immer du tust Benenne es).

Wenn dies der Fall ist, würde ich (in Paket a) ein exportiert Funktion

%Vor%

Was den Vertrag korrekt dokumentiert und von Paketen genutzt werden kann b und c mit Typen, die einen Walker implementieren, um ihre Implementierungen zu testen in b_test.go und c_test.go. IMHO ist es vollkommen in Ordnung, dass diese Funktionen wie TestWalkerContract werden von godoc angezeigt.

P.S. Häufiger als Walk and Tired könnte ein Fehlerzustand sein die aufbewahrt und gemeldet wird, bis gelöscht / zurückgesetzt.

    
Volker 17.04.2013 07:51
quelle

Tags und Links