Mi informacion de contacto
Correo[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
En el lenguaje Go, las pruebas unitarias se implementan a través del paquete de pruebas en la biblioteca estándar, que proporciona un conjunto de funciones que hacen que escribir, ejecutar y administrar pruebas unitarias sea simple y eficiente.
Reglas de nomenclatura de archivos de prueba
La regla de nomenclatura del archivo de prueba en Go es agregar_test.go
.Por ejemplo, si tienes uncalculator.go
archivo, el archivo de prueba correspondiente debe sercalculator_test.go
。
Reglas de nomenclatura para funciones de prueba
La función de prueba debe comenzar conTest
comienza y puede ir seguido de cualquier cadena que no esté vacía, por ejemploTestAdd
、TestSubtract
esperar.
usar testing.T
Hacer afirmaciones y reportar errores
En la función de prueba, usetesting.T
Escriba parámetros para gestionar el estado y la salida de la prueba.puedes usart.Error*
、t.Fail*
y otros métodos para indicar fallas de prueba y generar información de error relevante.
Una función de calculadora se define en el paquete de calculadora y la implementación específica es la siguiente:
package calculator
func Add(a, b int) int {
return a + b
}
En el directorio actual, creamos un archivo de prueba calculadora_test.go y definimos una función de prueba de la siguiente manera:
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)
}
}
Para ejecutar esta prueba unitaria, utilice el comando go test.En la línea de comando, ingrese el directorio que contiene calculadora.go y calculadora_prueba.go, y luego ejecutego test
, estos resultados son los siguientes
go test
PASS
ok modu 0.226s
Agregue la siguiente función de prueba en calculadora_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)
}
}
Para ver mejor la ejecución de cada caso de prueba en los resultados de salida, podemosgo test -v
parámetros para permitirle generar resultados de prueba completos.
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
El comando puede ejecutar pruebas según el modo especificado. Este comando admite expresiones regulares para seleccionar funciones de prueba para ejecutar.
Por ejemplo, después de corregir el caso de uso TestAdd2, pasego tes -run=Add2
Ejecute solo el caso de prueba TestAdd2, el resultado es
go test -run=Add2 -v
=== RUN TestAdd2
--- PASS: TestAdd2 (0.00s)
PASS
ok modu 0.198s
4. Omita algunos casos de prueba
Agregar nueva función de prueba
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)
}
}
al ejecutargo test -shor
Cuando t, se omitirátesting.Short()
El caso de prueba marcado, el resultado es
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
A través de grupos de prueba y subpruebas, puede agregar más casos de prueba y ver los resultados de una manera más amigable.
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)
}
})
}
}
corrergo test -v
,apagar
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
El lenguaje Go admite inherentemente la concurrencia, por lo que al agregart.Parallel()
Lograr la paralelización de las pruebas de conducción.
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)
}
})
}
}
usargo test -cover
para ver la cobertura de la prueba
go test -cover
PASS
modu coverage: 100.0% of statements
ok modu 1.149s
Al realizar pruebas unitarias en lenguaje Go, dado que la función de aserción oficial no está incorporada, generalmente necesitamos usar una gran cantidad deif...else...
declaración para verificar los resultados de la prueba.Sin embargo, al utilizar bibliotecas de terceros comotestify/assert
, podemos llamar fácilmente a una variedad de funciones de aserción de uso común, que no solo simplifican el código de prueba, sino que también generan información de descripción de error clara y fácil de entender, lo que nos ayuda a localizar rápidamente el problema.
En el ejemplo anterior, utilizamosif...else...
Declaración para verificar los resultados de las pruebas.
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 ahoratestify/assert
El proceso de juicio anterior se simplifica de la siguiente manera:
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
tenertestify/assert
Todas las funciones de aserción, la única diferencia entre ellas es quetestify/require
Si se encuentra un caso de prueba fallido, la prueba finalizará inmediatamente.