Go memiliki pengujian bawaan melalui paket testing dan perintah go test — tidak perlu framework eksternal. Tes hidup di file _test.go, dan Go sangat menekankan table-driven tests, benchmarks, dan tooling yang baik sebagai fitur kelas pertama.
Go memiliki pengujian bawaan melalui paket testing dan perintah go test — tidak perlu framework eksternal. Tes hidup di file _test.go, dan Go sangat menekankan table-driven tests, benchmarks, dan tooling yang baik sebagai fitur kelas pertama.
// math.go
func Add(a, b int) int { return a + b }
// math_test.go — same package, _test.go suffix
import "testing"
func TestAdd(t *testing.T) { // Test prefix + *testing.T parameter
result := Add(2, 3)
if result != 5 {
t.Errorf("Add(2,3) = %d; want 5", result) // report failure (continues)
// t.Fatalf stops the test immediately
}
}
// run with: go test (or `go test -v` for verbose, `go test ./...` for all packages)
Fungsi tes dimulai dengan Test, mengambil *testing.T, dan melaporkan kegagalan melalui t.Errorf/t.Fatalf. Tidak ada kata kunci assertion — Anda memeriksa kondisi dengan if biasa dan melaporkan kegagalan (Go menyukai gaya eksplisit ini).
func TestAdd(t *testing.T) {
tests := []struct { // a table of test CASES
name string
a, b int
expected int
}{
{"positives", 2, 3, 5},
{"with zero", 0, 5, 5},
{"negatives", -1, -1, -2},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { // a SUBTEST per case (named, isolated)
if got := Add(tt.a, tt.b); got != tt.expected {
t.Errorf("Add(%d,%d) = %d; want %d", tt.a, tt.b, got, tt.expected)
}
})
}
}
Table-driven tests adalah idiom Go yang dominan — tentukan slice kasus, loop melaluinya dengan subtes t.Run. Ini membuat penambahan kasus menjadi trivial dan memberikan pelaporan pass/fail yang jelas dan individual per kasus.
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ { // the framework chooses b.N for statistical accuracy
Add(2, 3)
}
}
// go test -bench=. → reports ns/op (and -benchmem for allocations)
go test -cover # coverage percentage
go test -coverprofile=c.out # then: go tool cover -html=c.out (visual report)
go test -race # the RACE DETECTOR — finds data races (crucial for concurrency)
go test -run TestAdd # run specific tests
Flag -race sangat penting — mendeteksi data races dalam kode concurrent, alat kunci mengingat fokus Go pada concurrency.
func TestMain(m *testing.M) { // package-level setup/teardown
setup()
code := m.Run()
teardown()
os.Exit(code)
}
// t.Helper() marks a function as a test helper (better failure line reporting)
// httptest package for testing HTTP handlers; interfaces for mocking dependencies
Pengujian adalah bagian bawaan kelas pertama dari Go — paket testing dan go test tidak memerlukan framework eksternal, mencerminkan penekanan Go pada pengujian sebagai praktik inti.
Memahami konvensi adalah pengetahuan penting sehari-hari: file _test.go dan struktur TestXxx(t *testing.T), gaya pelaporan kegagalan eksplisit (tanpa assertion), dan terutama pola table-driven test yang mendominasi Go idiomatis (mencakup banyak kasus secara kompak dengan pelaporan per-kasus yang jelas melalui subtes).
Sama pentingnya adalah benchmarks bawaan Go (performa sebagai kekhawatiran yang dapat diuji) dan tooling yang kuat — analisis coverage dan terutama detektor -race, yang menemukan data races dalam kode concurrent (vital mengingat penggunaan Go yang heavy pada concurrency).
Mengetahui cara menulis tes Go yang efektif dan idiomatis, menggunakan race detector, dan memanfaatkan httptest/interfaces untuk menguji komponen nyata adalah ciri khas pengembangan Go profesional dan topik yang sering muncul mencerminkan fluency kualitas kode.