Go-Tests meistern
Ethan Miller
Product Engineer · Leapcell

Organisation von Testdateien
In Go befinden sich Testdateien normalerweise im selben Paket wie die Quelldateien, die getestet werden, und folgen diesen Namenskonventionen:
- Quelldatei: xxx.go
- Testdatei: xxx_test.go
Testdateinamen müssen mit _test.go
enden, damit die Go-Toolchain sie erkennen und als Testdateien behandeln kann.
Signatur von Testfunktionen
Testfunktionen müssen die folgende Signatur haben:
func TestXxx(t *testing.T) { ... }
- Der Funktionsname beginnt mit
Test
, gefolgt vom Namen der Funktion oder des Features, das getestet wird (normalerweise mit einem Großbuchstaben am Anfang). - Er akzeptiert einen einzigen Parameter
*testing.T
, der verwendet wird, um Testfehler zu melden und Informationen zu protokollieren.
Schreiben von Testfunktionen
Basisbeispiel
Angenommen, es gibt eine einfache Additionsfunktion Add
, die sich in der Datei math.go
befindet:
// math.go package mathutil func Add(a, b int) int { return a + b }
Die entsprechende Testdatei math_test.go
kann wie folgt geschrieben werden:
// math_test.go package mathutil import ( "testing" ) func TestAdd(t *testing.T) { tests := []struct { a, b, expected int }{ {1, 2, 3}, {0, 0, 0}, {-1, 1, 0}, } for _, tt := range tests { result := Add(tt.a, tt.b) if result != tt.expected { t.Errorf("Add(%d, %d) = %d; expected %d", tt.a, tt.b, result, tt.expected) } } }
Verwenden von Subtests
Go 1.7 hat Subtests eingeführt, wodurch es bequemer ist, mehrere verwandte Tests innerhalb derselben Testfunktion auszuführen:
func TestAdd(t *testing.T) { tests := []struct { a, b, expected int }{ {1, 2, 3}, {0, 0, 0}, {-1, 1, 0}, } for _, tt := range tests { t.Run(fmt.Sprintf("%d+%d", tt.a, tt.b), func(t *testing.T) { result := Add(tt.a, tt.b) if result != tt.expected { t.Errorf("Add(%d, %d) = %d; expected %d", tt.a, tt.b, result, tt.expected) } }) } }
Verwenden von tabellengesteuerten Tests
Tabellengesteuerte Tests sind ein gängiges Muster, bei dem eine Reihe von Eingaben und erwarteten Ausgaben definiert werden, um das Verhalten einer Funktion zu testen:
func TestMultiply(t *testing.T) { tests := []struct { a, b, expected int }{ {2, 3, 6}, {0, 5, 0}, {-2, 4, -8}, } for _, tt := range tests { t.Run(fmt.Sprintf("%d*%d", tt.a, tt.b), func(t *testing.T) { result := Multiply(tt.a, tt.b) if result != tt.expected { t.Errorf("Multiply(%d, %d) = %d; expected %d", tt.a, tt.b, result, tt.expected) } }) } }
Ausführen von Tests
Verwenden des Befehls go test
Führen Sie im Paketverzeichnis, das die Testdateien enthält, den folgenden Befehl aus, um alle Tests auszuführen:
go test
Ausführen spezifischer Tests
Um eine bestimmte Testfunktion auszuführen, können Sie den Parameter -run
verwenden, der reguläre Ausdrücke unterstützt:
go test -run TestAdd
Anzeigen der detaillierten Ausgabe
Verwenden Sie das Flag -v
, um die detaillierte Ausgabe für jede Testfunktion anzuzeigen:
go test -v
Ausführen von Tests parallel
Verwenden Sie t.Parallel()
, um Testfunktionen gleichzeitig auszuführen und die Testeffizienz zu verbessern:
func TestSomething(t *testing.T) { t.Parallel() // Test code }
Beim Ausführen von Tests können Sie die Anzahl der parallel auszuführenden Tests mit -parallel
angeben:
go test -parallel 4
Testabdeckung
Verwenden Sie go test -cover
, um die Testabdeckung zu überprüfen.
Generieren Sie eine Abdeckungsdatei:
go test -coverprofile=coverage.out go tool cover -html=coverage.out
Verwenden Sie go test -cover
, um die Testabdeckung zu überprüfen.
Generieren Sie eine Abdeckungsdatei:
go test -coverprofile=coverage.out go tool cover -html=coverage.out
Beispiel: Vollständiger Test-Workflow
Hier ist ein umfassendes Beispiel, das zeigt, wie man schreibt, ausführt und die Testabdeckung überprüft.
Quellcode
// mathutil/math.go package mathutil func Add(a, b int) int { return a + b } func Multiply(a, b int) int { return a * b }
Testcode
// mathutil/math_test.go package mathutil import ( "testing" ) func TestAdd(t *testing.T) { tests := []struct { a, b, expected int }{ {1, 2, 3}, {0, 0, 0}, {-1, 1, 0}, } for _, tt := range tests { t.Run(fmt.Sprintf("%d+%d", tt.a, tt.b), func(t *testing.T) { result := Add(tt.a, tt.b) if result != tt.expected { t.Errorf("Add(%d, %d) = %d; expected %d", tt.a, tt.b, result, tt.expected) } }) } }
Ausführen von Tests und Abdeckung
go test -v -coverprofile=coverage.out go tool cover -html=coverage.out
Go bietet leistungsstarke und prägnante Testwerkzeuge, die das Schreiben und Verwalten von Tests sehr bequem machen. Durch die richtige Organisation von Testdateien, das Schreiben von testbarem Code und die regelmäßige Überprüfung der Testabdeckung können Entwickler die Codequalität und -zuverlässigkeit sicherstellen. In Kombination mit Continuous Integration wird automatisiertes Testen zu einem wichtigen Mittel zur Sicherstellung der Projektstabilität.
Wir sind Leapcell, Ihre erste Wahl für das Hosten von Go-Projekten.
Leapcell ist die Serverless-Plattform der nächsten Generation für Webhosting, asynchrone Aufgaben und Redis:
Mehrsprachige Unterstützung
- Entwickeln Sie mit Node.js, Python, Go oder Rust.
Stellen Sie unbegrenzt Projekte kostenlos bereit
- Zahlen Sie nur für die Nutzung – keine Anfragen, keine Gebühren.
Unschlagbare Kosteneffizienz
- Pay-as-you-go ohne Leerlaufgebühren.
- Beispiel: 25 US-Dollar unterstützen 6,94 Millionen Anfragen bei einer durchschnittlichen Antwortzeit von 60 ms.
Optimierte Entwicklererfahrung
- Intuitive Benutzeroberfläche für mühelose Einrichtung.
- Vollständig automatisierte CI/CD-Pipelines und GitOps-Integration.
- Echtzeitmetriken und Protokollierung für umsetzbare Erkenntnisse.
Mühelose Skalierbarkeit und hohe Leistung
- Automatisches Skalieren zur einfachen Bewältigung hoher Parallelität.
- Null Betriebsaufwand – konzentrieren Sie sich einfach auf das Bauen.
Erfahren Sie mehr in der Dokumentation!
Folgen Sie uns auf X: @LeapcellHQ