2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Dans le langage Go, les tests unitaires sont implémentés via le package de test de la bibliothèque standard, qui fournit un ensemble de fonctions rendant l'écriture, l'exécution et la gestion des tests unitaires simples et efficaces.
Tester les règles de dénomination des fichiers
La règle de dénomination des fichiers de test dans Go consiste à ajouter_test.go
.Par exemple, si vous avez uncalculator.go
fichier, le fichier de test correspondant doit êtrecalculator_test.go
。
Règles de dénomination des fonctions de test
La fonction de test doit commencer parTest
commence et peut être suivi de n'importe quelle chaîne non vide, par exempleTestAdd
、TestSubtract
attendez.
utiliser testing.T
Faire des assertions et signaler des erreurs
Dans la fonction test, utiliseztesting.T
Saisissez des paramètres pour gérer l’état et la sortie des tests.vous pouvez utilisert.Error*
、t.Fail*
et d'autres méthodes pour indiquer l'échec du test et produire des informations d'erreur pertinentes.
Une fonction de calculatrice est définie dans le package de calculatrice, et l'implémentation spécifique est la suivante :
package calculator
func Add(a, b int) int {
return a + b
}
Dans le répertoire courant, nous créons un fichier de test calculator_test.go et définissons une fonction de test comme suit :
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)
}
}
Pour exécuter ce test unitaire, utilisez la commande go test.Dans la ligne de commande, entrez le répertoire contenant calculator.go et calculator_test.go, puis exécutezgo test
, ces résultats sont les suivants
go test
PASS
ok modu 0.226s
Ajoutez la fonction de test suivante dans calculator_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)
}
}
Afin de mieux voir l'exécution de chaque scénario de test dans les résultats de sortie, nous pouvonsgo test -v
paramètres pour lui permettre de produire des résultats de test complets.
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
go test -run
La commande peut exécuter des tests selon le mode spécifié. Cette commande prend en charge les expressions régulières pour sélectionner les fonctions de test à exécuter.
Par exemple, après avoir corrigé le cas d'utilisation TestAdd2, transmettezgo tes -run=Add2
Exécutez uniquement le scénario de test TestAdd2, le résultat est
go test -run=Add2 -v
=== RUN TestAdd2
--- PASS: TestAdd2 (0.00s)
PASS
ok modu 0.198s
4. Ignorer certains cas de test
Ajouter une nouvelle fonction de 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)
}
}
lors de l'exécutiongo test -shor
Quand t, il sera ignorétesting.Short()
Le cas de test marqué, le résultat est
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
Grâce aux groupes de tests et aux sous-tests, vous pouvez ajouter davantage de cas de test et visualiser les résultats de manière plus conviviale.
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)
}
})
}
}
courirgo test -v
,s'avérer
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
Le langage Go prend intrinsèquement en charge la concurrence, donc en ajoutantt.Parallel()
Réaliser la parallélisation des tests de pilotes.
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)
}
})
}
}
utilisergo test -cover
pour voir la couverture des tests
go test -cover
PASS
modu coverage: 100.0% of statements
ok modu 1.149s
Lors de la réalisation de tests unitaires en langage Go, étant donné que la fonction d'assertion officielle n'est pas intégrée, nous devons généralement utiliser un grand nombre deif...else...
déclaration pour vérifier les résultats des tests.Cependant, en utilisant des bibliothèques tierces telles quetestify/assert
, nous pouvons facilement appeler une variété de fonctions d'assertion couramment utilisées, qui non seulement simplifient le code de test, mais génèrent également des informations de description d'erreur claires et faciles à comprendre pour nous aider à localiser rapidement le problème.
Dans l'exemple ci-dessus, nous utilisonsif...else...
Déclaration pour vérifier les résultats des tests
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)
}
})
}
Disponible dès maintenanttestify/assert
Le processus de jugement ci-dessus est simplifié comme suit :
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
result := Add(tc.x, tc.y)
assert.Equal(t, result, tc.expected)
})
}
testify/require
avoirtestify/assert
Toutes les fonctions d'assertion, la seule différence entre elles esttestify/require
Si un scénario de test ayant échoué est rencontré, le test sera immédiatement terminé.