Wie man die Testabdeckung in Go misst und nicht verrückt wird
\n\nSie haben Tests für Ihre Go-Anwendung geschrieben. Fühlen Sie sich wie ein Superheld? Das tun Sie zu Recht. Aber es gibt einen Haken: Wie viel Code ist tatsächlich durch Tests abgedeckt? Ohne eine Antwort auf diese Frage ist Ihre Zuversicht nur Kaffeesatzleserei.
\n\nDie Frage "How to measure test coverage in Go" ist eine der beliebtesten auf Stack Overflow (Zehntausende von Aufrufen). Und das ist kein Zufall. Entwickler wollen nicht nur Tests schreiben, sondern verstehen, wie effektiv sie sind. In diesem Tutorial behandeln wir alle Methoden zur Messung der Testabdeckung in Go: von grundlegenden Befehlen bis hin zu fortgeschrittenen Techniken mit Profilen und HTML-Berichten.
\n\nWas ist Testabdeckung und warum sollte man sie messen?
\n\nTestabdeckung (Code Coverage) ist eine Metrik, die angibt, wie viel Prozent Ihres Quellcodes während der Tests ausgeführt wird. Sie wird in Prozent ausgedrückt. 100% Abdeckung ist nicht immer der Heilige Gral, aber es lohnt sich, nach hohen Werten zu streben.
\n\nWarum ist das nötig?
\n- \n
- Qualitätskontrolle: Sie sehen, welche Codebereiche ohne Tests geblieben sind \n
- Vertrauen beim Refactoring: Eine hohe Abdeckung verringert das Risiko, etwas zu beschädigen \n
- CI/CD-Metriken: Sie können einen Abdeckungsschwellenwert festlegen und Code mit niedriger Abdeckung ablehnen \n
- Dokumentation: Tests sind lebendige Dokumentation, und die Abdeckung zeigt, wie vollständig sie ist \n
Der Haken: Abdeckung ≠ Testqualität
\nDenken Sie daran: 100% Abdeckung garantiert keine fehlerfreie Software. Man kann Tests schreiben, die einfach Funktionen aufrufen, aber nichts überprüfen. Abdeckung ist eine quantitative Metrik. Die Qualität der Tests ist qualitativ. Verwenden Sie beide Ansätze.
\n\nGrundlegende Messung: go test -cover
\n\nBeginnen wir mit dem Einfachsten. Go bietet integrierte Unterstützung für die Abdeckung direkt im Werkzeug go test. Lassen Sie uns ein einfaches Projekt erstellen und sehen, wie es funktioniert.
Erstellen Sie die Datei math.go:
package main\n\nfunc Add(a, b int) int {\n return a + b\n}\n\nfunc Subtract(a, b int) int {\n return a - b\n}\n\nfunc Multiply(a, b int) int {\n return a * b\n}\n\nfunc Divide(a, b int) (int, error) {\n if b == 0 {\n return 0, nil // Fehler: sollte return 0, errors.New("division by zero") sein\n }\n return a / b, nil\n}\n\nUnd nun der Test (math_test.go):
package main\n\nimport "testing"\n\nfunc TestAdd(t *testing.T) {\n result := Add(2, 3)\n if result != 5 {\n t.Errorf("expected 5, got %d", result)\n }\n}\n\nfunc TestSubtract(t *testing.T) {\n result := Subtract(10, 4)\n if result != 6 {\n t.Errorf("expected 6, got %d", result)\n }\n}\n\n// Absichtlich nicht getestet: Multiply und Divide\n\nFühren wir nun die Tests mit dem Flag -cover aus:
go test -cover\n\nDie Ausgabe sieht ungefähr so aus:
\n\nok example/math 0.002s coverage: 50.0% of statements\n\nDas stimmt – 50% des Codes sind abgedeckt, weil Multiply und Divide nicht getestet werden. Aber das ist nur eine Gesamtzahl. Was, wenn wir ein detailliertes Abdeckungsprofil sehen möchten?
Abdeckungsprofil: go test -coverprofile
\n\nDas Flag -coverprofile speichert detaillierte Informationen über die Abdeckung in einer Datei:
go test -coverprofile=coverage.out\n\nJetzt befindet sich im Ordner die Datei coverage.out. Öffnen Sie sie – es ist ein Textformat, bei dem jede Zeile zeigt, ob eine bestimmte Codeanweisung ausgeführt wurde. Aber sie manuell zu lesen ist langweilig. Kommen wir zur Visualisierung.
HTML-Bericht: go tool cover -html
\n\nDie bequemste Methode zur Analyse der Abdeckung ist der HTML-Bericht. Er hebt ausgeführten Code grün und nicht ausgeführten Code rot hervor.
\n\ngo tool cover