Go语言实践测试

85 阅读3分钟

单元测试规则

  • 所有测试文件以_test.go结尾
  • 所有的测试方法以 func TestXxx(*testing.T),如果这个命名和实现正确在文件会有个可以运行的标志
  • 初始化逻辑放到TestMain中 TestMain结构大致如下
func TestMain(m *testing.M){
	//测试前:数据装载、配置初始化等前置工作
	code := m.Run()
	//测试后:释放资源等收尾工作
	os.Exit(code)
}

覆盖率

go test judement_test.go judement.go--cover

用来测试你的测试代码中的覆盖程度是否已经测试完全了。

单元测试的Tips

  • 一般覆盖率:50%~60%,较高覆盖率80%
  • 测试分支相互独立、全面覆盖
  • 测试单元粒度足够小,函数单一职责

单元测试Mock

这里推荐的是monkey:github.com/bouk/monkey

快速Mock函数

  • 为一个函数打桩
  • 为一个方法打桩

能够使得自己的测试方法不再依赖本地的文件

基准测试

简介

Go 语言的基准测试是一种测量程序性能的方法,通常用于测试函数或代码片段的执行速度。基准测试与单元测试相似,都是通过 testing 包实现的,但基准测试的目标是性能评估,而非功能验证。

功能

  • 优化代码,需要对当前的代码分析
  • 内置的测试框架提供了基准测试的能力

基本结构

Go 中的基准测试使用函数名以 Benchmark 开头,并接受 *testing.B 类型的参数。 基准测试的基本函数签名为:

func BenchmarkXxx(b *testing.B) {
    for i := 0; i < b.N; i++ {
        // 要测试的代码
    }
}
  • b *testing.B:
    • 提供控制循环执行次数的功能。
    • 包含统计基准测试结果的方法。
  • b.N:
    • 决定基准测试的循环次数,由 Go 的测试框架自动调整以保证测试时间足够长。
  • 循环测试:
    • b.N 是动态调整的次数,因此测试代码必须写在循环中。

示例代码

测试字符串的拼接功能

package main

import (
    "strings"
    "testing"
)

func BenchmarkConcatStrings(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = "Hello" + " " + "World"
    }
}

func BenchmarkJoinStrings(b *testing.B) {
    for i := 0; i < b.N; i++ {
        _ = strings.Join([]string{"Hello", "World"}, " ")
    }
}

运行基准测试

go test -bench=.

输出:

BenchmarkConcatStrings-8    1000000000           0.3584 ns/op
BenchmarkJoinStrings-8      2000000000           0.5023 ns/op

常用命令

运行基准测试

go test -bench=.

-bench=.: 运行所有基准测试。

指定基准测试函数

go test -bench=BenchmarkFuncName

输出更多详细信息

go test -bench=. -benchmem

-benchmem:输出内存分配统计信息,包括每次操作的分配次数和字节数。

优化基准测试

避免测试干扰

  • 消除IO操作:基准测试中尽量避免网络或文件操作,因为这些操作会导致测试结果不稳定
  • 避免打印操作:fmt.Println等打印操作会增加基准测试的时间

控制内存分配

可以通过-benchmem查看内存分配情况,从而优化代码

基准测试结果解读

BenchmarkConcatStrings-8    1000000000           0.3584 ns/op
BenchmarkJoinStrings-8      2000000000           0.5023 ns/op

字段解释

  • BenchmarkConcatStrings-8: 基准测试的名字和运行的逻辑 CPU 数(如 8)。
  • 1000000000: 基准测试的循环次数(b.N 的值)。
  • 0.3584 ns/op: 每次操作的平均耗时(纳秒)。