testing.T.Cleanup în Go

Înregistrează o funcție de curățenie care rulează după ce testul (și subtestele lui) s-au terminat.

Sintaxă
func (c *T) Cleanup(f func())

Ce face testing.T.Cleanup

t.Cleanup(f) e ca un defer legat de test: f rulează când testul se termină, chiar dacă a eșuat sau a fost oprit cu t.Fatal. Funcțiile înregistrate rulează în ordine inversă (ultima înregistrată, prima executată).

Avantajul față de defer: o funcție ajutătoare poate înregistra singură curățenia pentru resursa pe care o creează (o bază de date de test, un server, un fișier), iar testul nu mai trebuie să știe de ea. În plus, Cleanup așteaptă și subtestele paralele, pe când defer ar rula prea devreme.

Parametri

Parametru Descriere
f Funcția de curățenie.

Ce returnează

Nimic.

Exemple

Exemplul 1: Ordinea curățeniei

// fișierul cleanup_test.go
package magazin

import "testing"

func TestOrdine(t *testing.T) {
    t.Cleanup(func() { t.Log("curățenie 1: închid conexiunea") })
    t.Cleanup(func() { t.Log("curățenie 2: șterg datele de test") })
    t.Log("rulez testul")
}

Rezultatul în terminal (timpii diferă la fiecare rulare)

$ go test -v
=== RUN   TestOrdine
    cleanup_test.go:8: rulez testul
    cleanup_test.go:7: curățenie 2: șterg datele de test
    cleanup_test.go:6: curățenie 1: închid conexiunea
--- PASS: TestOrdine (0.00s)
PASS
ok  	magazin	0.224s

Exemplul 2: Funcție ajutătoare cu curățenie proprie

// fișierul server_test.go
package magazin

import (
    "io"
    "net/http"
    "net/http/httptest"
    "testing"
)

// serverTest pornește un server de test și îl oprește singur la final.
func serverTest(t *testing.T) *httptest.Server {
    t.Helper()
    srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, `{"stoc": 12}`)
    }))
    t.Cleanup(func() {
        srv.Close()
        t.Log("server de test oprit")
    })
    return srv
}

func TestStoc(t *testing.T) {
    srv := serverTest(t)
    resp, err := http.Get(srv.URL)
    if err != nil {
        t.Fatal(err)
    }
    defer resp.Body.Close()
    corp, _ := io.ReadAll(resp.Body)
    if string(corp) != `{"stoc": 12}` {
        t.Errorf("răspuns %s", corp)
    }
}

Rezultatul în terminal (timpii diferă la fiecare rulare)

$ go test -v
=== RUN   TestStoc
    server_test.go:18: server de test oprit
--- PASS: TestStoc (0.00s)
PASS
ok  	magazin	0.316s

Greșeli frecvente

  • Folosești defer pentru curățenie într-un test cu subteste paralele. defer rulează înainte ca subtestele să se termine; folosește t.Cleanup.

Comenzi înrudite

  • testing.T.TempDir: Creează un director temporar nou pentru test și îl șterge automat când testul se termină.
  • testing.T.Helper: Marchează o funcție ca ajutătoare, ca erorile raportate din ea să arate linia din test care a apelat-o.
  • testing.T.Parallel: Anunță că testul poate rula în paralel cu alte teste paralele, ca suita să se termine mai repede.