Lecții din modul (1/5)
Pachetul `testare`
În Go, testele sunt parte din stdlib: fără bibliotecă externă, fără cadru de configurat. Tot ce aveți nevoie este un fișier *_test.go lângă cod, câteva funcții TestXxx și comanda go test.
Convenții de bază
- Fișierele de testare sunt denumite
<something>_test.goși trăiesc în același pachet ca și codul pe care îl testează (sau într-un pachet<name>_testpentru „testele cutie neagră”). - Funcțiile de testare au o semnătură exactă:
func TestXxx(t *testing.T)undeXxxîncepe cu o literă mare. - Importați
testingdin stdlib. - Nu
assertEquals: foloseștiif got != want { t.Errorf(...) }cufmt-verbe.
// 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)
}
}Rulați-l cu:
go test ./... # all packages in the module
go test -v ./pkg # verbose: prints test names
go test -run TestSum # only tests matching the regext.Error vs t.Fatal
Acestea sunt cele două verbe de bază pentru a semnala un eșec:
| Metoda | Efect |
|---|---|
t.Log(args...) | Înregistrează, dar nu eșuează (vizibil numai cu -v sau în caz de eșec). |
t.Error(args...) | Înregistrează, marchează FAIL, continuă funcția de testare. |
t.Errorf(fmt, ...) | Precum Error cu formatare. |
t.Fatal(args...) | Înregistrează, marchează FAIL, oprește testul (apelează runtime.Goexit). |
t.Fatalf(fmt, ...) | Precum Fatal cu formatare. |
Regula generală: utilizați Fatal atunci când continuarea nu are sens (de exemplu, configurare eșuată, dereferire iminentă a indicatorului zero); în caz contrar, Error, care vă permite să vedeți toate eșecurile într-o singură rulare.
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
}Configurați și demontați cu t.Cleanup
Pentru a elibera resurse la sfârșitul unui test (sau sub-test), utilizați t.Cleanup în loc de defer:
func TestDB(t *testing.T) {
db := newTestDB(t)
t.Cleanup(func() { db.Close() })
// ... test
}Avantajul față de defer: asistentul care creează db poate înregistra curățarea intern, astfel încât apelanții nu trebuie să-l amintească.
Testează ajutoarele
Metoda t.Helper() marchează o funcție ca „ajutor”: atunci când un test eșuează, urmărirea stivei omite funcția de ajutor și indică direct apelantul:
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
}Exerciții
Definiți funcția TestSum care verifică Sum(2,3) == 5 folosind t.Errorf cu un mesaj formatat.
Soluție disponibilă după 3 încercări
În TestDiv, utilizați t.Fatal pentru a opri imediat testul dacă Div returnează o valoare neașteptată.
Soluție disponibilă după 3 încercări
Care este diferența fundamentală dintre t.Error și t.Fatal?
if err != nil {
t.???(err)
}