13 Testen in Go

Tests sind ein essenzieller Bestandteil der Softwareentwicklung, um sicherzustellen, dass Ihr Code korrekt und zuverlässig funktioniert.

13.1 Grundlagen des Testens

Go hat ein integriertes Testframework, das einfach zu verwenden und in die Sprache integriert ist. Testdateien enden in der Regel auf _test.go und befinden sich im selben Verzeichnis wie der zu testende Code.

13.1.1 Einfache Unit-Tests

Ein Unit-Test in Go wird mit der Funktion TestName definiert, wobei Name ein beschreibender Name für den Test ist. Hier ein einfaches Beispiel:

package mymath

import "testing"

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    if result != 5 {
        t.Errorf("Add(2, 3) = %d; want 5", result)
    }
}

In diesem Beispiel:

  1. Wir erstellen eine Testdatei mymath_test.go.
  2. Wir importieren das Paket testing, das Funktionen und Typen für das Schreiben von Tests bereitstellt.
  3. Wir definieren die Funktion TestAdd, die die Funktion Add testet.
  4. Innerhalb der Testfunktion überprüfen wir das Ergebnis der Add-Funktion. Wenn das Ergebnis nicht 5 ist, verwenden wir t.Errorf, um einen Fehler anzuzeigen.

13.1.2 Ausführen von Tests

Um Tests auszuführen, verwenden Sie das Kommando go test im Terminal:

go test

Dies führt alle Tests in Ihrem Paket aus und zeigt die Ergebnisse an.

13.2 Tabellengetriebene Tests

Tabellengetriebene Tests sind eine nützliche Technik, um mehrere Eingaben und erwartete Ausgaben in einem einzigen Testfall zu überprüfen. Hier ein Beispiel:

package mymath

import "testing"

func TestAdd(t *testing.T) {
    tests := []struct {
        a, b int
        want int
    }{
        {2, 3, 5},
        {1, 1, 2},
        {0, 0, 0},
    }

    for _, tt := range tests {
        t.Run(fmt.Sprintf("Add(%d,%d)", tt.a, tt.b), func(t *testing.T) {
            got := Add(tt.a, tt.b)
            if got != tt.want {
                t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want)
            }
        })
    }
}

In diesem Beispiel:

  1. Wir erstellen eine Liste von Testfällen mit verschiedenen Eingaben und erwarteten Ausgaben.
  2. Wir verwenden eine Schleife, um jeden Testfall zu durchlaufen.
  3. Innerhalb der Schleife verwenden wir t.Run, um jeden Testfall als Subtest auszuführen. Dies ermöglicht detailliertere Fehlermeldungen und eine bessere Strukturierung der Tests.

13.3 Benchmark-Tests

Go unterstützt auch Benchmark-Tests, um die Leistung Ihres Codes zu messen. Benchmark-Tests verwenden die Funktion BenchmarkName. Hier ein Beispiel:

package mymath

import "testing"

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}

In diesem Beispiel:

  1. Wir definieren die Funktion BenchmarkAdd, die die Leistung der Funktion Add misst.
  2. Innerhalb der Benchmark-Funktion verwenden wir eine Schleife, um die Funktion Add b.N-mal auszuführen. Der Wert von b.N wird von der Testumgebung bestimmt und hängt von der Laufzeit des Tests ab.

Um Benchmark-Tests auszuführen, verwenden Sie das Kommando go test -bench .:

go test -bench .

Dies führt alle Benchmark-Tests in Ihrem Paket aus und zeigt die Ergebnisse an.

13.4 Testabdeckung

Um die Testabdeckung Ihres Codes zu überprüfen, verwenden Sie das Kommando go test -cover:

go test -cover

Dies zeigt den Prozentsatz des Codes an, der von Ihren Tests abgedeckt wird. Sie können auch detailliertere Berichte mit go test -coverprofile=coverage.out und go tool cover -html=coverage.out erstellen:

go test -coverprofile=coverage.out
go tool cover -html=coverage.out

Dies generiert eine HTML-Datei, die eine detaillierte Übersicht über die Testabdeckung Ihres Codes bietet.