Modül dersleri (1/5)
'Test' paketi
Go'da testler stdlib'in bir parçasıdır: harici kitaplık yoktur, yapılandırılacak çerçeve yoktur. İhtiyacınız olan tek şey, kodun yanında bir *_test.go dosyası, birkaç TestXxx işlevi ve go test komutudur.
Temel kurallar
- Test dosyaları
<something>_test.goolarak adlandırılır ve test ettikleri kodla aynı pakette bulunur (veya "kara kutu testleri" için<name>_testpaketindedir). - Test fonksiyonlarının tam bir imzası vardır:
func TestXxx(t *testing.T)buradaXxxbüyük harfle başlar. testingstdlib'den içe aktarıyorsunuz.- Hayır
assertEquals:if got != want { t.Errorf(...) }'yufmt-fiilleriyle kullanırsınız.
// 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)
}
}Şununla çalıştırın:
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 ve t.Fatal
Bunlar bir başarısızlığın sinyalini veren iki temel fiildir:
| Yöntem | Efekt |
|---|---|
t.Log(args...) | Günlüğe kaydeder ancak başarısız olmaz (yalnızca -v ile veya başarısızlık durumunda görünür). |
t.Error(args...) | Günlüğe kaydeder, FAIL olarak işaretler, test fonksiyonuna devam eder. |
t.Errorf(fmt, ...) | Biçimlendirmeyle Error gibi. |
t.Fatal(args...) | Günlüğe kaydeder, FAIL olarak işaretler, testi durdurur (runtime.Goexit çağrılır). |
t.Fatalf(fmt, ...) | Biçimlendirmeyle Fatal gibi. |
Temel kural: Devam etmenin bir anlamı olmadığında Fatal kullanın (ör. başarısız kurulum, yakında sıfır işaretçi referansı); aksi halde Error, bu da tüm hataları tek bir çalıştırmada görmenizi sağlar.
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
}t.Cleanup ile kurulum ve sökme
Kaynakları bir testin (veya alt testin) sonunda serbest bırakmak için defer yerine t.Cleanup kullanın:
func TestDB(t *testing.T) {
db := newTestDB(t)
t.Cleanup(func() { db.Close() })
// ... test
}defer'e göre avantajı: db'u oluşturan yardımcı temizleme işlemini dahili olarak kaydedebilir, böylece arayanların bunu hatırlamasına gerek kalmaz.
Test yardımcıları
t.Helper() yöntemi bir işlevi "yardımcı" olarak işaretler: bir test başarısız olduğunda yığın izlemesi yardımcı işlevi atlar ve doğrudan çağıranı işaret eder:
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
}Egzersizler
Biçimlendirilmiş bir mesajla t.Errorf kullanarak Sum(2,3) == 5'i doğrulayan TestSum işlevini tanımlayın.
3 denemeden sonra çözüm mevcut
TestDiv'de, Div'in beklenmedik bir değer döndürmesi durumunda testi hemen durdurmak için t.Fatal'ı kullanın.
3 denemeden sonra çözüm mevcut
t.Error ve t.Fatal arasındaki temel fark nedir?
if err != nil {
t.???(err)
}