„Kann ich nur eine einzige Datei mit Tests ausführen?“ – Ja, und hier ist, wie das in Go geht
Saßen Sie schon einmal vor dem Terminal, haben go test ./... eingegeben und mit Entsetzen beobachtet, wie die gesamte Codebasis Ihres Go-Projekts Hunderte von Tests durchläuft? Dabei mussten Sie doch nur eine einzige kleine Datei mit Testfällen überprüfen, die Sie gerade fertiggestellt hatten. Kommt Ihnen das bekannt vor? Wenn ja, sind Sie hier genau richtig.
In diesem Artikel behandeln wir eine häufig gestellte Frage auf Stack Overflow (die übrigens tausende Aufrufe hat): „How to run test cases in a specified file?“. Wir passen die Antworten an die Realität eines Go-Entwicklers an und zeigen nicht nur grundlegende Befehle, sondern auch Lifehacks, die Ihnen Stunden Arbeit ersparen. Los geht's!
Warum ist einfaches go test nicht immer geeignet?
In großen Projekten werden Tests in Modul-, Integrations- und End-to-End-Tests unterteilt. Wenn Sie go test ./... ausführen, durchläuft Go rekursiv alle Unterpakete und führt alle gefundenen Tests aus. Das kann Minuten dauern. Und wenn Sie Tests haben, die auf eine Datenbank oder externe APIs zugreifen, können diese aus Gründen fehlschlagen, die nicht in Ihrer Hand liegen. Daher ist die Fähigkeit, Testfälle in einer bestimmten Datei auszuführen, nicht nur eine Bequemlichkeit, sondern eine Fähigkeit eines professionellen Entwicklers.
Der grundlegende Befehl: go test mit Dateinamen
Der direkteste Weg ist, die spezifische Datei mit den Tests anzugeben. Aber hier gibt es einen Haken: Go verlangt, dass Sie sowohl die zu testende Datei als auch die Datei mit den Tests zusammen angeben. Warum? Weil der Compiler den gesamten Code des Pakets zusammenbauen muss.
Angenommen, Sie haben folgende Projektstruktur:
myproject/├── main.go└── math_utils.go└── math_utils_test.goUm die Tests nur aus math_utils_test.go auszuführen, führen Sie Folgendes aus:
go test -v math_utils.go math_utils_test.goDas Flag -v (verbose) gibt detaillierte Informationen zu jedem Testfall aus. Ohne es sehen Sie nur das Ergebnis: PASS oder FAIL.
Beispiel für echten Code
Erstellen wir eine einfache Datei math_utils.go:
package main
func Sum(a, b int) int { return a + b}
func Multiply(a, b int) int { return a * b}Und die Testdatei math_utils_test.go:
package main
import "testing"
func TestSum(t *testing.T) { result := Sum(2, 3) if result != 5 { t.Errorf("Sum(2, 3) = %d; want 5", result) }}
func TestMultiply(t *testing.T) { result := Multiply(3, 4) if result != 12 { t.Errorf("Multiply(3, 4) = %d; want 12", result) }}Jetzt führen wir es aus:
$ go test -v math_utils.go math_utils_test.go=== RUN TestSum--- PASS: TestSum (0.00s)=== RUN TestMultiply--- PASS: TestMultiply (0.00s)PASSok command-line-arguments 0.002sBeachten Sie die Ausgabe: ok command-line-arguments. Das bedeutet, dass Go ein temporäres Paket aus den angegebenen Dateien erstellt hat. Dieser Ansatz funktioniert, hat aber Einschränkungen.
Das Problem mit mehreren Dateien in einem Paket
Wenn Ihr Paket aus mehreren Dateien besteht (z. B. math_utils.go und strings_utils.go) und der Test in math_utils_test.go eine Funktion aus strings_utils.go aufruft, wird der obige Befehl mit einem Kompilierungsfehler fehlschlagen. Go wird sich beschweren, dass die Funktion nicht definiert ist.
Die Lösung besteht darin, alle abhängigen Dateien aufzulisten. Das ist aber umständlich. Besser ist es, einen anderen Ansatz zu verwenden.
Fortgeschrittener Weg: Filtern von Tests nach Namen (-run)
Das Flag -run ermöglicht es Ihnen, nur die Testfälle auszuführen, deren Namen einem regulären Ausdruck entsprechen. Das ist keine Bindung an eine Datei, aber wenn Sie Ihre Tests sinnvoll benannt haben, können Sie die gewünschten leicht herausfiltern.
Beispiel: Führen Sie alle Tests aus, die mit TestSum beginnen:
go test -v -run T