Lentelės testai — pagaunam 7 pamokos klaidą
Vienas įėjimas viename teste — per plona. Tikras funkcijas reikia tikrinti su keliais atvejais — įprastu, kraštiniu, klastingu. Rašyti atskirą Test… kiekvienam — triukšmas. Go idioma — lentelės pavidalo testas (table-driven): {įėjimas, want} eilučių sąrašas ir vienas ciklas, tikrinantis visas.
Prisimink charCount iš 7 pamokos — jis grąžina, kiek simbolių eilutėje. Štai jo lentelės testas:
func TestCharCount(t *testing.T) {
cases := []struct {
in string
want int
}{
{"obuolys", 7},
{"ąžuolas", 7}, // lietuviškai: 7 simboliai, bet 9 baitai
{"Go", 2},
{"", 0},
}
for _, c := range cases {
got := charCount(c.in)
if got != c.want {
t.Errorf("charCount(%q) = %d, want %d", c.in, got, c.want)
}
}
}
cases := []struct{…}{…} — anoniminės struktūros sąrašas: vienkartinis tipas, egzistuojantis vien eilutėms išvardyti. Kiekviena eilutė — vienas atvejis; ciklas paleidžia visus ir praneša kiekvieną neatitikimą atskirai. Naujas atvejis — viena eilutė, ne nauja funkcija.
Dabar ašis — šis testas yra spąstai, pastatyti tikrai klaidai. Prisimink 7 pamoką: naivus būdas skaičiuoti simbolius yra len(s), ir jis klaidingas lietuviškai, nes len skaičiuoja baitus, o „ą" — 2 baitai. Tarkim, charCount vis dar turi klaidą:
func charCount(s string) int {
return len(s) // KLAIDA: skaičiuoja BAITUS, ne simbolius
}
Paleisk go test:
--- FAIL: TestCharCount (0.00s)
text_test.go:18: charCount("ąžuolas") = 9, want 7
FAIL
FAIL yourapp 1.7s
Štai ji. Mašina pagavo — = 9, want 7 — tiksliai tą klaidą, įvardintą, dar prieš kuriam nors vartotojui įvedant lietuvišką pavadinimą. Jokio spoksojimo į išvestį, jokio spėliojimo: krentanti eilutė rodo tiesiai į sugedusį atvejį.
Dabar pataisyk charCount taip, kaip mokė 7 pamoka:
import "unicode/utf8"
func charCount(s string) int {
return utf8.RuneCountInString(s) // skaičiuoja SIMBOLIUS
}
Paleisk go test dar kartą:
ok yourapp 0.5s
O su -v matai jį praeinantį pavadinimu:
=== RUN TestCharCount
--- PASS: TestCharCount (0.00s)
PASS
Tai ir yra visa testavimo esmė. 7 pamokos klaida slėpdavosi, kol konkretus įėjimas ją paliesdavo jau naudojime. Dabar testas ją prisimena amžinai: jei kada nors kas nors „supaprastins" charCount atgal į len, testas taps raudonas per kitą paleidimą. Testas — tai klaida, kurią pagauti reikia tik kartą.
Toliau: parašyk pilną testų failą savo programai — charCount, truncateRunes ir validateTitle, visi viename _test.go.