Direct naar de hoofdinhoud
Module 9 · Les 1 van 541/50 in de cursus~12 min
Modulelessen (1/5)

Het `test`-pakket

In Go zijn tests onderdeel van de stdlib: geen externe bibliotheek, geen raamwerk om te configureren. Het enige wat je nodig hebt is een *_test.go bestand naast de code, een paar TestXxx functies en de opdracht go test.

Basisconventies

  • Testbestanden hebben de naam <something>_test.go en bevinden zich in hetzelfde pakket als de code die ze testen (of in een <name>_test pakket voor "black-box-tests").
  • Testfuncties hebben een exacte handtekening: func TestXxx(t *testing.T) waarbij Xxx begint met een hoofdletter.
  • Je importeert testing uit de stdlib.
  • Nee assertEquals: je gebruikt if got != want { t.Errorf(...) } met fmt-werkwoorden.
Go
// math.go
package math

func Sum(a, b int) int { return a + b }

// math_test.go
package math

import "testing"

func TestSum(t *testing.T) {
    got := Sum(2, 3)
    if got != 5 {
        t.Errorf("Sum(2,3) = %d; voglio %d", got, 5)
    }
}

Voer het uit met:

Bash
go test ./...        # all packages in the module
go test -v ./pkg     # verbose: prints test names
go test -run TestSum  # only tests matching the regex

t.Error versus t.Fatal

Dit zijn de twee basiswerkwoorden om een ​​fout aan te geven:

WerkwijzeEffect
t.Log(args...)Registreert maar faalt niet (alleen zichtbaar met -v of bij falen).
t.Error(args...)Registreert, markeert FAIL, gaat door met de testfunctie.
t.Errorf(fmt, ...)Vind Error leuk met opmaak.
t.Fatal(args...)Registreert, markeert FAIL, stopt de test (roept runtime.Goexit aan).
t.Fatalf(fmt, ...)Vind Fatal leuk met opmaak.

Vuistregel: gebruik Fatal als doorgaan geen zin heeft (bijvoorbeeld een mislukte installatie, dreigende nul-pointer-dereferentie); anders Error, waarmee u alle fouten in één keer kunt zien.

Go
func TestOpen(t *testing.T) {
    f, err := os.Open("fixtures/sample.txt")
    if err != nil {
        t.Fatal(err) // if it doesn't open, the next steps would fail on nil
    }
    defer f.Close()
    // ... assert on content with t.Errorf
}

Opzetten en afbreken met t.Cleanup

Om bronnen vrij te geven aan het einde van een test (of subtest), gebruik je t.Cleanup in plaats van defer:

Go
func TestDB(t *testing.T) {
    db := newTestDB(t)
    t.Cleanup(func() { db.Close() })
    // ... test
}

Het voordeel ten opzichte van defer: de helper die db aanmaakt, kan de opruiming intern registreren, zodat bellers dit niet hoeven te onthouden.

Helpers testen

De t.Helper() methode markeert een functie als een "helper": wanneer een test mislukt, slaat de stacktrace de helperfunctie over en verwijst deze rechtstreeks naar de aanroeper:

Go
func mustParseInt(t *testing.T, s string) int {
    t.Helper()
    n, err := strconv.Atoi(s)
    if err != nil {
        t.Fatalf("parse %q: %v", s, err)
    }
    return n
}

Oefeningen

Oefening#go.m9.l1.e1
Pogingen: 0Laden…

Definieer de TestSum-functie die Sum(2,3) == 5 verifieert met behulp van t.Errorf met een opgemaakt bericht.

Editor laden…

Oplossing beschikbaar na 3 pogingen

Oefening#go.m9.l1.e2
Pogingen: 0Laden…

Gebruik in TestDiv t.Fatal om de test onmiddellijk te stoppen als Div een onverwachte waarde retourneert.

Editor laden…

Oplossing beschikbaar na 3 pogingen

Quiz#go.m9.l1.e3
Klaar

Wat is het fundamentele verschil tussen t.Error en t.Fatal?

Go
if err != nil {
  t.???(err)
}
Antwoordmogelijkheden