Condivisione della tecnologia

Vai ai test unitari

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Nel linguaggio Go, lo unit test viene implementato tramite il pacchetto testing nella libreria standard, che fornisce un insieme di funzioni che rendono semplice ed efficiente la scrittura, l'esecuzione e la gestione degli unit test.

1. Regole

  • Testare le regole di denominazione dei file
    La regola di denominazione dei file di prova in Go è aggiungere_test.go .Ad esempio, se hai acalculator.go file, dovrebbe essere il file di test corrispondentecalculator_test.go

  • Regole di denominazione per le funzioni di test
    La funzione di test deve iniziare conTest inizia e può essere seguito da qualsiasi stringa non vuota, ad esempioTestAddTestSubtract Aspettare.

  • utilizzo testing.T Fare asserzioni e segnalare errori
    Nella funzione di test, utilizzaretesting.T Digitare i parametri per gestire lo stato e l'output del test.Puoi usaret.Error*t.Fail* e altri metodi per indicare il fallimento del test e fornire informazioni sugli errori rilevanti.

2. Esempio di test unitario

2.1 Singolo caso di test

Una funzione della calcolatrice è definita nel pacchetto della calcolatrice e l'implementazione specifica è la seguente:

package calculator

func Add(a, b int) int {
	return a + b
}
  • 1
  • 2
  • 3
  • 4
  • 5

Nella directory corrente creiamo un file di test calcolatrice_test.go e definiamo una funzione di test come segue:

package calculator

import "testing"


func TestAdd(t *testing.T) {
	result := Add(1, 2)
	expected := 3
	if result != expected {
		t.Errorf("Add(1,2) return %d, expected %d", result, expected)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Per eseguire questo test unitario, utilizzare il comando go test.Nella riga di comando, inserisci la directory contenente calcolatrice.go e calcolatrice_test.go, quindi eseguigo test, questi risultati sono i seguenti

go test
PASS
ok      modu    0.226s
  • 1
  • 2
  • 3

2.2 Casi di test multipli

Aggiungi la seguente funzione di test in calcolatrice_test.go:

func TestAdd2(t *testing.T) {
	result := Add(3, 2)
	expected := 3
	if result != expected {
		t.Errorf("Add(1,2) return %d, expected %d", result, expected)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Per vedere meglio l'esecuzione di ciascun caso di test nei risultati di output, possiamogo test -vparametri per consentire l'output dei risultati completi del test.

go test -v
=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
=== RUN   TestAdd2
    calculator_test.go:17: Add(1,2) return 5, expected 3
--- FAIL: TestAdd2 (0.00s)
FAIL
exit status 1
FAIL    modu    0.216s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.3 Specificare i casi di test in esecuzione

go test -run Il comando può eseguire test in base alla modalità specificata. Questo comando supporta le espressioni regolari per selezionare le funzioni di test da eseguire.

Ad esempio, dopo aver corretto il caso d'uso TestAdd2, passarego tes -run=Add2Esegui solo il test case TestAdd2, il risultato è

go test -run=Add2 -v
=== RUN   TestAdd2
--- PASS: TestAdd2 (0.00s)
PASS
ok      modu    0.198s
  • 1
  • 2
  • 3
  • 4
  • 5

4. Salta alcuni casi di test
Aggiungi una nuova funzione di test

func TestAdd3(t *testing.T) {
	if testing.Short() {
        t.Skip("short模式下会跳过该测试用例")
    }
	
	result := Add(3, 2)
	expected := 5
	if result != expected {
		t.Errorf("Add(1,2) return %d, expected %d", result, expected)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

durante l'esecuzionego test -shorQuando t, verrà saltatotesting.Short()Il caso di prova contrassegnato, il risultato è

go test -short -v
=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
=== RUN   TestAdd2
--- PASS: TestAdd2 (0.00s)
=== RUN   TestAdd3
    calculator_test.go:23: short模式下会跳过该测试用例
--- SKIP: TestAdd3 (0.00s)
PASS
ok      modu    0.635s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3. Gruppi di test e sottotest

3.1 Gruppi di test e sottotest

Attraverso gruppi di test e test secondari, puoi aggiungere più casi di test e visualizzare i risultati in modo più intuitivo

func TestAdd(t *testing.T) {
	tests := []struct {
		name     string
		x, y     int
		expected int
	}{
		{"Add1", 1, 2, 3},
		{"Add2", 3, 3, 6},
		{"Add3", 4, 5, 8},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			result := Add(tc.x, tc.y)
			if result != tc.expected {
				t.Errorf("Add(%d, %d) returned %d, expected %d", tc.x, tc.y, result, tc.expected)
			}
		})
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

correrego test -v,rivelarsi

go test -v
=== RUN   TestAdd
=== RUN   TestAdd/Add2
=== RUN   TestAdd/Add3
    calculator_test.go:51: Add(4, 5) returned 9, expected 8
--- FAIL: TestAdd (0.00s)
    --- PASS: TestAdd/Add1 (0.00s)
    --- PASS: TestAdd/Add2 (0.00s)
    --- FAIL: TestAdd/Add3 (0.00s)
FAIL
exit status 1
FAIL    modu    0.190s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.2 Test paralleli

Il linguaggio Go supporta intrinsecamente la concorrenza, quindi aggiungendot.Parallel()Per ottenere la parallelizzazione dei test dei conducenti.

func TestAdd(t *testing.T) {
	t.Parallel()  // 将 TLog 标记为能够与其他测试并行运行
	// 这里使用匿名结构体定义了若干个测试用例
	// 并且为每个测试用例设置了一个名称
	tests := []struct {
		name     string
		x, y     int
		expected int
	}{
		{"Add1", 1, 2, 3},
		{"Add2", 3, 3, 6},
		{"Add3", 4, 5, 8},
	}

	for _, tc := range tests {
		tc := tc  // 注意这里重新声明tt变量(避免多个goroutine中使用了相同的变量)
		t.Run(tc.name, func(t *testing.T) {
			t.Parallel()  // 将每个测试用例标记为能够彼此并行运行
			result := Add(tc.x, tc.y)
			if result != tc.expected {
				t.Errorf("Add(%d, %d) returned %d, expected %d", tc.x, tc.y, result, tc.expected)
			}
		})
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3.3 Copertura del test

utilizzogo test -coverper visualizzare la copertura del test

go test -cover
PASS
        modu    coverage: 100.0% of statements
ok      modu    1.149s
  • 1
  • 2
  • 3
  • 4

4. Vai al kit di strumenti per test unitari: testimonia

Quando si eseguono test unitari in linguaggio Go, poiché la funzione di asserzione ufficiale non è incorporata, di solito è necessario utilizzare un gran numero diif...else... dichiarazione per verificare i risultati del test.Tuttavia, utilizzando librerie di terze parti cometestify/assert, possiamo facilmente richiamare una varietà di funzioni di asserzione di uso comune, che non solo semplificano il codice di test, ma generano anche informazioni sulla descrizione dell'errore chiare e di facile comprensione per aiutarci a individuare rapidamente il problema.

Nell'esempio sopra, usiamoif...else...Dichiarazione per verificare i risultati del test

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			result := Add(tc.x, tc.y)
			if result != tc.expected {
				t.Errorf("Add(%d, %d) returned %d, expected %d", tc.x, tc.y, result, tc.expected)
			}
		})
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Disponibile oratestify/assertIl procedimento di giudizio di cui sopra è semplificato come segue:

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			result := Add(tc.x, tc.y)
			assert.Equal(t, result, tc.expected)
		})
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

testify/requireAveretestify/assertTutte le funzioni di asserzione, l'unica differenza tra loro ètestify/requireSe viene riscontrato un caso di test fallito, il test verrà interrotto immediatamente.