minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Na linguagem Go, o teste unitário é implementado por meio do pacote de testes na biblioteca padrão, que fornece um conjunto de funções que tornam a escrita, a execução e o gerenciamento de testes unitários simples e eficientes.
Testar regras de nomenclatura de arquivos
A regra de nomenclatura de arquivo de teste em Go é adicionar_test.go
.Por exemplo, se você tiver umcalculator.go
arquivo, o arquivo de teste correspondente deve sercalculator_test.go
。
Regras de nomenclatura para funções de teste
A função de teste deve começar comTest
começa e pode ser seguido por qualquer string não vazia, por exemploTestAdd
、TestSubtract
espere.
usar testing.T
Faça afirmações e relatórios de erros
Na função de teste, usetesting.T
Digite parâmetros para gerenciar o status e a saída do teste.você pode usart.Error*
、t.Fail*
e outros métodos para indicar falha no teste e gerar informações de erro relevantes.
Uma função de calculadora é definida no pacote da calculadora e a implementação específica é a seguinte:
package calculator
func Add(a, b int) int {
return a + b
}
No diretório atual, criamos um arquivo de teste calculator_test.go e definimos uma função de teste da seguinte forma:
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 executar este teste de unidade, use o comando go test.Na linha de comando, insira o diretório que contém calculator.go e calculator_test.go e executego test
, esses resultados são os seguintes
go test
PASS
ok modu 0.226s
Adicione a seguinte função de teste em 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)
}
}
Para ver melhor a execução de cada caso de teste nos resultados de saída, podemosgo test -v
parâmetros para permitir a saída de resultados de teste 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
O comando pode executar testes de acordo com o modo especificado. Este comando oferece suporte a expressões regulares para selecionar funções de teste a serem executadas.
Por exemplo, após corrigir o caso de uso TestAdd2, passego tes -run=Add2
Execute apenas o caso de teste TestAdd2, o resultado é
go test -run=Add2 -v
=== RUN TestAdd2
--- PASS: TestAdd2 (0.00s)
PASS
ok modu 0.198s
4. Pule alguns casos de teste
Adicionar nova função de teste
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)
}
}
ao executargo test -shor
Quando t, será ignoradotesting.Short()
O caso de teste marcado, o resultado é
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
Através de grupos de testes e subtestes, você pode adicionar mais casos de testes e visualizar os resultados de uma forma mais amigável
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
,vire para fora
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
A linguagem Go oferece suporte inerente à simultaneidade, portanto, ao adicionart.Parallel()
Para conseguir paralelização de testes de driver.
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 visualizar a cobertura do teste
go test -cover
PASS
modu coverage: 100.0% of statements
ok modu 1.149s
Ao realizar testes unitários na linguagem Go, como a função de asserção oficial não está integrada, geralmente precisamos usar um grande número deif...else...
declaração para verificar os resultados do teste.No entanto, usando bibliotecas de terceiros, comotestify/assert
, podemos chamar facilmente uma variedade de funções de asserção comumente usadas, que não apenas simplificam o código de teste, mas também geram informações de descrição de erro claras e fáceis de entender, ajudando-nos a localizar rapidamente o problema.
No exemplo acima, usamosif...else...
Declaração para verificar os resultados do teste
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)
}
})
}
Disponível agoratestify/assert
O processo de julgamento acima é simplificado da seguinte forma:
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
tertestify/assert
Todas as funções de asserção, a única diferença entre elas é quetestify/require
Se um caso de teste com falha for encontrado, o teste será encerrado imediatamente.