深色模式
Go单元测试 
什么是单元测试 
单元测试是对软件中最小的可测试部分(称为单元)进行验证,以确保其按预期工作。在Go中,单元通常是函数或方法。通过编写单元测试,可以在代码更改时快速发现问题,确保代码的稳定性和可靠性。
Go中的测试文件结构 
在Go中,测试文件需要满足以下条件:
- 文件命名:测试文件必须以_test.go结尾。
- 包名:可以与被测试代码的包名相同,或以_test作为后缀。
- 测试函数:测试函数以Test开头,遵循TestXxx的命名格式,其中Xxx可以是任何名称,但首字母需大写。
- 函数签名:测试函数接受一个指向testing.T类型的指针作为参数,例如:func TestSomething(t *testing.T)。
示例,为math.go编写测试代码math_test.go:
go
package math
// Add 函数返回两个整数的和
func Add(a, b int) int {
    return a + b
}go
package math
import "testing"
// TestAdd 测试 Add 函数
func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5
    if result != expected {
        t.Errorf("Add(2, 3) = %d; 想要 %d", result, expected)
    }
}编写基本的测试函数 
测试函数用于验证代码的正确性。在测试函数中,可以使用testing包提供的方法,如:
- t.Error(args ...):报告错误但继续执行测试。
- t.Errorf(format string, args ...):格式化错误消息并报告错误。
- t.Fail():标记测试失败但继续执行。
- t.FailNow():标记测试失败并立即中止。
- t.Fatal(args ...):报告错误并中止测试。
- t.Fatalf(format string, args ...):格式化错误消息,报告错误并中止测试。
- t.Log(args ...):记录测试信息。
示例:
go
func TestSubtract(t *testing.T) {
    result := Subtract(5, 3)
    expected := 2
    if result != expected {
        t.Fatalf("Subtract(5, 3) = %d; 想要 %d", result, expected)
    }
}运行测试 
在终端中,进入包含测试文件的目录,使用以下命令运行测试:
bash
go test如果要查看测试的详细信息,可以使用-v标志:
bash
go test -v要运行特定的测试函数,可以使用-run标志:
bash
go test -run TestAdd表驱动测试 
表驱动测试是一种编写测试的模式,使用一组输入和期望的输出来测试函数的多个场景。这种方式可以让测试代码更加简洁和可读。
示例:
go
func TestMultiply(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"正数相乘", 2, 3, 6},
        {"零相乘", 0, 5, 0},
        {"负数相乘", -1, 5, -5},
        {"大数相乘", 100, 100, 10000},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Multiply(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Multiply(%d, %d) = %d; 想要 %d", tt.a, tt.b, result, tt.expected)
            }
        })
    }
}测试覆盖率 
测试覆盖率用于衡量测试代码覆盖了被测试代码的多少。
查看覆盖率百分比:
bash
go test -cover生成覆盖率报告:
bash
go test -coverprofile=coverage.out
go tool cover -html=coverage.out上述命令将在浏览器中打开一个覆盖率报告的HTML页面,直观地显示哪些代码被测试覆盖,哪些没有。
基准测试 
基准测试用于测量函数的性能。基准函数以Benchmark开头,接受*testing.B类型的参数。
示例:
go
func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(1, 2)
    }
}运行基准测试:
bash
go test -bench=.其中,-bench=.表示运行所有基准测试。
示例函数 
示例函数用于生成文档和展示代码的用法。示例函数以Example开头,不需要参数或返回值。
示例:
go
func ExampleAdd() {
    fmt.Println(Add(2, 3))
    // Output: 5
}在运行go test时,Go会验证示例函数的输出是否与注释中的// Output:一致。
编写好的测试的最佳实践 
- 保持测试的独立性:测试之间不应互相依赖,每个测试应独立运行。
- 使用表驱动测试:当测试同一函数的多个输入输出时,表驱动测试可以提高代码的可读性和维护性。
- 覆盖边界条件:测试应涵盖正常情况、边界条件和异常情况。
- 使用辅助函数:当有重复的测试逻辑时,提取为辅助函数,减少代码重复。
- 清理测试环境:使用defer和t.Cleanup清理测试中创建的资源,确保测试环境的整洁。
- 避免在测试中使用全局变量:全局变量可能导致测试之间的相互影响,尽量避免。
- 命名清晰:测试函数和测试用例的名称应清晰描述其测试的内容。
