Ce face teste (testing)
Go are testarea integrată, fără biblioteci externe. Testele stau în fișiere care se termină cu _test.go, lângă codul testat. Fiecare test este o funcție func TestXxx(t *testing.T); dacă rezultatul nu este cel așteptat, testul raportează cu t.Errorf (continuă) sau t.Fatalf (se oprește). Fișierele _test.go nu intră în programul compilat cu go build.
Stilul obișnuit în Go este testul pe tabel: un slice de cazuri (intrare, rezultat așteptat) parcurs într-o buclă, fiecare caz rulat ca subtest cu t.Run(nume, ...). Funcțiile BenchmarkXxx(b *testing.B) măsoară viteza (rulate cu go test -bench .), iar funcțiile ExampleXxx cu un comentariu // Output: sunt în același timp teste și exemple în documentație.
Metodele lui testing.T (Error, Fatal, Run, Helper, Cleanup, TempDir, Parallel) au pagini proprii în secțiunea pachetului testing.
Exemple
Exemplul 1: Test pe tabel cu subteste
Fișierul preturi/preturi_test.go; rezultatul vine din go test -v ./preturi.
package preturi
import (
"math"
"testing"
)
func TestCuTVA(t *testing.T) {
if got := CuTVA(100); math.Abs(got-121) > 1e-9 {
t.Errorf("CuTVA(100) = %v, vreau 121", got)
}
}
func TestReducere(t *testing.T) {
cazuri := []struct {
nume string
pret, procent float64
vreau float64
}{
{"fără reducere", 200, 0, 200},
{"zece la sută", 200, 10, 180},
{"jumătate", 50, 50, 25},
}
for _, c := range cazuri {
t.Run(c.nume, func(t *testing.T) {
if got := Reducere(c.pret, c.procent); math.Abs(got-c.vreau) > 1e-9 {
t.Errorf("Reducere(%v, %v) = %v, vreau %v", c.pret, c.procent, got, c.vreau)
}
})
}
}
Rezultat în terminal
=== RUN TestCuTVA
--- PASS: TestCuTVA (0.00s)
=== RUN TestReducere
=== RUN TestReducere/fără_reducere
=== RUN TestReducere/zece_la_sută
=== RUN TestReducere/jumătate
--- PASS: TestReducere (0.00s)
--- PASS: TestReducere/fără_reducere (0.00s)
--- PASS: TestReducere/zece_la_sută (0.00s)
--- PASS: TestReducere/jumătate (0.00s)
PASS
ok exemplu.ro/magazin/preturi 0.230s
Exemplul 2: Un test care eșuează
Am greșit formula în Reducere (procent/10 în loc de procent/100). Mesajul arată fișierul, rândul și cazurile care au picat.
go test ./preturi
Rezultat în terminal
--- FAIL: TestReducere (0.00s)
--- FAIL: TestReducere/zece_la_sută (0.00s)
preturi_test.go:27: Reducere(200, 10) = 0, vreau 180
--- FAIL: TestReducere/jumătate (0.00s)
preturi_test.go:27: Reducere(50, 50) = -200, vreau 25
FAIL
FAIL exemplu.ro/magazin/preturi 0.289s
FAIL
Exemplul 3: Exemplu testabil și benchmark
go test verifică dacă ExampleCuTVA afișează exact textul din // Output:. b.Loop() (Go 1.24) repetă corpul de câte ori e nevoie pentru o măsurare stabilă.
// preturi/exemple_test.go
package preturi
import (
"fmt"
"testing"
)
func ExampleCuTVA() {
fmt.Printf("%.2f\n", CuTVA(50))
// Output: 60.50
}
func BenchmarkReducere(b *testing.B) {
for b.Loop() {
Reducere(199.99, 15)
}
}
// în terminal:
// go test -bench . ./preturi
Rezultat în terminal
goos: darwin
goarch: arm64
pkg: exemplu.ro/magazin/preturi
cpu: Apple M1 Pro
BenchmarkReducere-10 553138562 2.257 ns/op
PASS
ok exemplu.ro/magazin/preturi 1.545s
Greșeli frecvente
- Funcția de test scrisă
TestreduceresautestReducere: dupăTesttrebuie o majusculă, altfel nu este rulată (go vetavertizează). - Fișierul numit
preturi_teste.gosautest_preturi.go: trebuie să se termine exact cu_test.go. t.Fatalapelat dintr-o goroutine pornită de test: nu oprește testul corect; foloseștet.Errorși sincronizare.- Compararea numerelor reale cu
==în teste: folosește o toleranță.
Comenzi înrudite
go test: Compilează și rulează testele (fișierele _test.go) și raportează ce a trecut și ce a picat.module și pachete: Un pachet este un director cu fișiere .go; un modul (go.mod) este un proiect cu mai multe pachete și dependențele lor.go vet: Analizează codul și semnalează greșeli probabile pe care compilatorul le acceptă: formate Printf greșite, copieri de mutex etc.