Berbagi teknologi

Lakukan pengujian unit

2024-07-12

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

Dalam bahasa Go, pengujian unit diimplementasikan melalui paket pengujian di perpustakaan standar, yang menyediakan serangkaian fungsi yang membuat penulisan, pengoperasian, dan pengelolaan pengujian unit menjadi sederhana dan efisien.

1. Aturan

  • Uji aturan penamaan file
    Aturan penamaan file uji di Go adalah menambahkan_test.go .Misalnya, jika Anda memilikicalculator.go file, file tes yang sesuai seharusnyacalculator_test.go

  • Aturan penamaan untuk fungsi pengujian
    Fungsi pengujian harus dimulai denganTest dimulai, dan dapat diikuti oleh string apa pun yang tidak kosong, misalnyaTestAddTestSubtract Tunggu.

  • menggunakan testing.T Buat pernyataan dan pelaporan kesalahan
    Dalam fungsi pengujian, gunakantesting.T Ketik parameter untuk mengelola status dan keluaran pengujian.Anda dapat gunakant.Error*t.Fail* dan metode lain untuk menunjukkan kegagalan pengujian dan menghasilkan informasi kesalahan yang relevan.

2. Contoh pengujian unit

2.1 Kasus uji tunggal

Fungsi kalkulator didefinisikan dalam paket kalkulator, dan implementasi spesifiknya adalah sebagai berikut:

package calculator

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

Di direktori saat ini, kami membuat file pengujian kalkulator_test.go dan mendefinisikan fungsi pengujian sebagai berikut:

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

Untuk menjalankan pengujian unit ini, gunakan perintah go test.Di baris perintah, masukkan direktori yang berisi kalkulator.go dan kalkulator_test.go, lalu jalankango test, hasilnya adalah sebagai berikut

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

2.2 Beberapa kasus uji

Tambahkan fungsi tes berikut di kalkulator_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

Untuk melihat lebih baik eksekusi setiap kasus uji pada hasil keluaran, kita bisago test -vparameter agar dapat menampilkan hasil pengujian yang lengkap.

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 Tentukan kasus uji yang sedang berjalan

go test -run Perintah tersebut dapat menjalankan pengujian sesuai dengan mode yang ditentukan. Perintah ini mendukung ekspresi reguler untuk memilih fungsi pengujian yang akan dijalankan.

Misalnya, setelah memperbaiki kasus penggunaan TestAdd2, lulusgo tes -run=Add2Jalankan saja test case TestAdd2, hasilnya

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

4. Lewati beberapa test case
Tambahkan fungsi pengujian baru

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

saat mengeksekusigo test -shorJika t, itu akan dilewatitesting.Short()Kasus uji yang ditandai, hasilnya adalah

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. Kelompok tes dan subtes

3.1 Kelompok tes dan subtes

Melalui kelompok pengujian dan subtes, Anda dapat menambahkan lebih banyak kasus pengujian dan melihat hasilnya dengan cara yang lebih ramah

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

berlarigo test -v,beralih

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 Pengujian paralel

Bahasa Go pada dasarnya mendukung konkurensi, jadi dengan menambahkant.Parallel()Untuk mencapai paralelisasi tes pengemudi.

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 Cakupan tes

menggunakango test -coveruntuk melihat cakupan tes

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

4. Gunakan perangkat pengujian unit – bersaksi

Saat melakukan pengujian unit dalam bahasa Go, karena fungsi pernyataan resmi tidak ada di dalamnya, kita biasanya perlu menggunakan sejumlah besarif...else... pernyataan untuk memverifikasi hasil tes.Namun, dengan menggunakan perpustakaan pihak ketiga sepertitestify/assert, kita dapat dengan mudah memanggil berbagai fungsi pernyataan yang umum digunakan, yang tidak hanya menyederhanakan kode pengujian, tetapi juga menghasilkan informasi deskripsi kesalahan yang jelas dan mudah dipahami untuk membantu kita menemukan masalahnya dengan cepat.

Dalam contoh di atas, kami menggunakanif...else...Pernyataan untuk memverifikasi hasil tes

	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

Tersedia sekarangtestify/assertProses penilaian di atas disederhanakan sebagai berikut:

	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/requirememilikitestify/assertSemua fungsi penegasan, satu-satunya perbedaan di antara keduanya adalahtestify/requireJika ditemukan kasus uji yang gagal, pengujian akan segera dihentikan.