Ce face testing.T.Run
t.Run(nume, func(t *testing.T) {...}) creează un subtest. Fiecare subtest apare separat în rezultatul lui go test -v (TestReducere/fara_reducere), poate eșua independent și poate fi rulat singur cu go test -run 'TestReducere/fara'. Spațiile din nume devin _.
Tiparul cel mai folosit în Go este testul pe bază de tabel: un slice de cazuri (nume, intrare, rezultat așteptat) și o buclă care apelează t.Run pentru fiecare. Un t.Fatal într-un subtest oprește doar acel subtest.
Parametri
| Parametru | Descriere |
|---|---|
name |
Numele subtestului. |
f |
Funcția subtestului; primește propriul *testing.T. |
Ce returnează
true dacă subtestul a trecut (sau rulează în paralel), altfel false.
Exemple
Exemplul 1: Test pe bază de tabel
// fișierul reducere.go
package magazin
// Reducere returnează procentul de reducere: 5% de la 200 lei, 10% de la 500 lei.
func Reducere(total float64) int {
switch {
case total >= 500:
return 10
case total >= 200:
return 5
default:
return 0
}
}
// fișierul reducere_test.go
package magazin
import "testing"
func TestReducere(t *testing.T) {
cazuri := []struct {
nume string
total float64
vrem int
}{
{"fara reducere", 50, 0},
{"exact 200", 200, 5},
{"intre praguri", 350, 5},
{"peste 500", 640, 10},
}
for _, c := range cazuri {
t.Run(c.nume, func(t *testing.T) {
if got := Reducere(c.total); got != c.vrem {
t.Errorf("Reducere(%v) = %d, aștept %d", c.total, got, c.vrem)
}
})
}
}
Rezultatul în terminal (timpii diferă la fiecare rulare)
$ go test -v
=== RUN TestReducere
=== RUN TestReducere/fara_reducere
=== RUN TestReducere/exact_200
=== RUN TestReducere/intre_praguri
=== RUN TestReducere/peste_500
--- PASS: TestReducere (0.00s)
--- PASS: TestReducere/fara_reducere (0.00s)
--- PASS: TestReducere/exact_200 (0.00s)
--- PASS: TestReducere/intre_praguri (0.00s)
--- PASS: TestReducere/peste_500 (0.00s)
PASS
ok magazin 0.329s
Exemplul 2: Rularea unui singur subtest
Același cod; după / scrii (o parte din) numele subtestului, cu _ în loc de spații.
// aceleași fișiere reducere.go și reducere_test.go
Rezultatul în terminal (timpii diferă la fiecare rulare)
$ go test -v -run TestReducere/exact_200
=== RUN TestReducere
=== RUN TestReducere/exact_200
--- PASS: TestReducere (0.00s)
--- PASS: TestReducere/exact_200 (0.00s)
PASS
ok magazin 0.273s
Greșeli frecvente
- Dai nume identice subtestelor. Go adaugă
#01,#02și devine greu de găsit cazul care a eșuat; dă nume unice și descriptive. - Folosești
t-ul testului părinte în interiorul subtestului (func(_ *testing.T) { t.Errorf(...) }). Eroarea se atribuie părintelui; folosește parametrul subtestului.
Comenzi înrudite
testing.T: Tipul primit de fiecare funcție de test; prin el raportezi erori, scrii mesaje și controlezi testul.testing.T.Parallel: Anunță că testul poate rula în paralel cu alte teste paralele, ca suita să se termine mai repede.testing.T.Error: Marchează testul ca eșuat și scrie un mesaj, dar lasă testul să continue (Errorf formatează ca Printf).testing.T.Helper: Marchează o funcție ca ajutătoare, ca erorile raportate din ea să arate linia din test care a apelat-o.