Pelajaran modul (1/5)
Paket `pengujian`
Di Go, pengujian adalah bagian dari stdlib: tidak ada pustaka eksternal, tidak ada kerangka kerja yang perlu dikonfigurasi. Yang Anda perlukan hanyalah file *_test.go di samping kode, beberapa fungsi TestXxx, dan perintah go test.
Konvensi dasar
- File pengujian diberi nama
<something>_test.godan berada dalam paket yang sama dengan kode yang diuji (atau dalam paket<name>_testuntuk "pengujian kotak hitam"). - Fungsi pengujian memiliki tanda tangan tepat:
func TestXxx(t *testing.T)denganXxxdimulai dengan huruf besar. - Anda mengimpor
testingdari stdlib. - Tidak
assertEquals: Anda menggunakanif got != want { t.Errorf(...) }dengan kata kerjafmt.
// 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)
}
}Jalankan dengan:
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
Ini adalah dua kata kerja dasar yang menandakan kegagalan:
| Metode | Efek |
|---|---|
t.Log(args...) | Log tetapi tidak gagal (hanya terlihat dengan -v atau jika gagal). |
t.Error(args...) | Mencatat, menandai GAGAL, melanjutkan fungsi pengujian. |
t.Errorf(fmt, ...) | Seperti Error dengan format. |
t.Fatal(args...) | Mencatat, menandai GAGAL, menghentikan pengujian (memanggil runtime.Goexit). |
t.Fatalf(fmt, ...) | Seperti Fatal dengan format. |
Aturan praktisnya: gunakan Fatal ketika melanjutkan tidak masuk akal (misalnya, penyiapan gagal, dereferensi penunjuk nihil akan segera terjadi); jika tidak Error, yang memungkinkan Anda melihat semua kegagalan dalam sekali proses.
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
}Penyiapan dan pembongkaran dengan t.Cleanup
Untuk melepaskan sumber daya di akhir pengujian (atau subtes), gunakan t.Cleanup alih-alih defer:
func TestDB(t *testing.T) {
db := newTestDB(t)
t.Cleanup(func() { db.Close() })
// ... test
}Keuntungan dibandingkan defer: helper yang membuat db dapat mendaftarkan pembersihan secara internal, sehingga penelepon tidak perlu mengingatnya.
Tes pembantu
Metode t.Helper() menandai suatu fungsi sebagai "pembantu": ketika pengujian gagal, pelacakan tumpukan melewati fungsi pembantu dan menunjuk langsung ke pemanggil:
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
}Latihan
Tentukan fungsi TestSum yang memverifikasi Sum(2,3) == 5 menggunakan t.Errorf dengan pesan yang diformat.
Solusi tersedia setelah 3 upaya
Di TestDiv, gunakan t.Fatal untuk segera menghentikan pengujian jika Div mengembalikan nilai yang tidak diharapkan.
Solusi tersedia setelah 3 upaya
Apa perbedaan mendasar antara t.Error dan t.Fatal?
if err != nil {
t.???(err)
}