当前位置: 首页 > news >正文

Go test 命令完整指南:从基础到高级用法

1 概述

go test 是 Go 语言内置的测试工具,用于执行测试函数(test function)、基准函数(benchmark function)和示例函数(example function)。它会自动寻找 *_test.go 文件中符合命名规则的函数并执行。

1.1 测试文件命名规范

  • 测试文件必须以 _test.go 结尾
  • 正常编译操作(go build/go install)会忽略这些文件
  • 名称以 _. 开头的文件即使后缀是 _test.go 也会被忽略

1.2 测试函数类型

  • 测试函数:必须以 TestXXX 开头,接收 *testing.T 参数
  • 基准函数:必须以 BenchmarkXXX 开头,接收 *testing.B 参数
  • 示例函数:必须以 ExampleXXX 开头,为文档提供示例

2 基本用法和测试模式

2.1 运行测试的基本命令

# 运行当前目录所有测试
go test# 显示详细输出
go test -v# 运行所有包(包括子目录)
go test ./...# 运行特定包测试
go test math

2.2 测试运行模式

go test 有两种运行模式:

  1. 本地目录模式:在没有包参数时调用(如 go testgo test -v)。此模式下缓存是禁用的。

  2. 包列表模式:显示指定包参数时调用(如 go test mathgo test ./...)。此模式下会缓存成功的测试结果。

2.3 测试缓存管理

# 清理所有缓存,包括测试缓存
go clean -cache# 只清理测试缓存
go clean -testcache# 禁用缓存(使用-count=1)
go test -count=1

测试结果在以下情况下会被缓存:相同的测试二进制文件、命令行选项来自可缓存选项集合(-benchtime, -cpu, -list, -parallel, -run, -short, -v)。要禁用缓存,可使用除可缓存选项之外的任何测试选项。

3 测试函数编写与实践

3.1 测试函数结构

package mypackageimport "testing"func TestAdd(t *testing.T) {result := Add(1, 2)if result != 3 {t.Errorf("Add(1, 2) = %d, expected 3", result)}
}

3.2 表驱动测试

对于多个测试用例的场景,推荐使用表驱动测试:

func TestIsPalindrome(t *testing.T) {var tests = []struct {input stringwant  bool}{{"", true},{"a", true},{"aa", true},{"ab", false},{"kayak", true},{"A man, a plan, a canal: Panama", true},}for _, test := range tests {if got := IsPalindrome(test.input); got != test.want {t.Errorf("IsPalindrome(%q) = %v", test.input, got)}}
}

3.3 子测试(Subtests)

使用 t.Run() 创建子测试,可以更好地组织测试用例:

func TestSumSubTest(t *testing.T) {t.Run("1+2", func(t *testing.T) {val := Sum(1, 2)t.Log("1+2=", val)})t.Run("2+3", func(t *testing.T) {val := Sum(2, 3)t.Log("2+3=", val)})
}

3.4 并行测试

对于可以并行执行的测试,使用 t.Parallel()

func TestSumParallel(t *testing.T) {t.Parallel()// 测试逻辑
}func TestSumParallel2(t *testing.T) {t.Parallel()// 测试逻辑
}

使用 -parallel n 指定最大并发数。

3.5 测试初始化与清理

使用 TestMain 作为测试入口点,进行初始化和清理操作:

func TestMain(m *testing.M) {fmt.Printf("测试初始化\n")// 初始化代码exitCode := m.Run()// 清理代码fmt.Printf("测试清理\n")os.Exit(exitCode)
}

如果没有在 TestMain 中调用 m.Run(),除了 TestMain() 以外的其他 test 都不会执行。

4 基准测试(Benchmark)

4.1 基准测试函数结构

func BenchmarkAdd(b *testing.B) {for i := 0; i < b.N; i++ {Add(i, i+1)}
}

4.2 运行基准测试

# 运行所有基准测试
go test -bench=.# 运行特定基准测试
go test -bench=BenchmarkAdd# 显示内存分配统计
go test -bench=. -benchmem# 指定基准测试运行时间
go test -bench=. -benchtime=5s

4.3 基准测试计时器控制

对于需要复杂初始化的基准测试,可以控制计时器:

func BenchmarkComplexOperation(b *testing.B) {// 复杂的初始化操作,不计入基准测试时间setup()b.ResetTimer() // 重置计时器for i := 0; i < b.N; i++ {complexOperation()}
}

还可以使用 b.StopTimer()b.StartTimer() 来暂停和恢复计时。

5 常用参数和标志

5.1 测试选择参数

下表总结了常用的测试选择参数:

参数描述示例
-run运行匹配正则表达式的测试函数go test -run TestAdd
-bench运行匹配正则表达式的基准测试go test -bench BenchmarkAdd
-v详细输出,显示所有测试日志go test -v
-count运行每个测试/基准测试的次数go test -count=3
-timeout设置测试超时时间go test -timeout=30s

5.2 高级控制参数

# 随机化测试执行顺序
go test -shuffle=on# 遇到第一个失败测试就停止
go test -failfast# 设置并行测试数量
go test -parallel=4# 列出匹配的测试但不执行
go test -list="TestAdd"

5.3 覆盖率分析

# 启用覆盖率分析
go test -cover# 生成覆盖率文件
go test -coverprofile=cover.out# 查看详细的覆盖率报告
go tool cover -html=cover.out# 设置覆盖率模式
go test -covermode=count

覆盖率模式有三种:

  • set(布尔值):语句是否运行
  • count(整数):语句运行了多少次
  • atomic(整数):支持并发场景的计数

6 性能分析

Go test 支持生成多种性能分析文件:

6.1 生成性能分析数据

# CPU 性能分析
go test -cpuprofile=cpu.out# 内存分配分析
go test -memprofile=mem.out# 阻塞分析
go test -blockprofile=block.out# 执行跟踪
go test -trace=trace.out

6.2 分析性能数据

生成分析文件后,可以使用 go tool pprof 进行分析:

# 分析 CPU 性能
go tool pprof cpu.out# 分析内存分配
go tool pprof mem.out# 查看执行跟踪
go tool trace trace.out

7 高级特性与技巧

7.1 测试二进制文件操作

# 编译测试二进制文件但不运行
go test -c -o test_binary# 运行已编译的测试二进制文件
./test_binary -test.v -test.run=TestAdd# 编译带调试信息的测试二进制文件
go test -c -gcflags="all=-N -l" -o debug_binary

7.2 JSON 格式输出

对于自动化测试,可以输出 JSON 格式的结果:

go test -json

7.3 传递参数给测试二进制文件

使用 -args 将参数传递给测试程序:

func TestArgs(t *testing.T) {if !flag.Parsed() {flag.Parse()}argList := flag.Args()for _, arg := range argList {if arg == "cloud" {t.Log("Running in cloud mode.")}}
}

运行测试时传递参数:

go test -run TestArgs -v -args "cloud"

8 实际应用示例

8.1 完整的测试文件示例

package exampleimport ("flag""fmt""testing""time"
)var print boolfunc init() {flag.BoolVar(&print, "p", false, "print test log")
}func TestAdd(t *testing.T) {result := Add(1, 2)if result != 3 {t.Errorf("Add(1, 2) = %d, expected 3", result)}
}func BenchmarkAdd(b *testing.B) {for i := 0; i < b.N; i++ {Add(i, i+1)}
}func ExampleAdd() {sum := Add(1, 2)fmt.Println(sum)// Output: 3
}func TestMain(m *testing.M) {flag.Parse()fmt.Printf("测试初始化\n")exitCode := m.Run()fmt.Printf("测试清理\n")os.Exit(exitCode)
}

8.2 测试 HTTP 处理程序

package http_testimport ("net/http""net/http/httptest""testing"
)func TestHandler(t *testing.T) {req, err := http.NewRequest("GET", "/health", nil)if err != nil {t.Fatal(err)}rr := httptest.NewRecorder()handler := http.HandlerFunc(HealthHandler)handler.ServeHTTP(rr, req)if status := rr.Code; status != http.StatusOK {t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)}expected := `{"status":"healthy"}`if rr.Body.String() != expected {t.Errorf("handler returned unexpected body: got %v want %v",rr.Body.String(), expected)}
}

9 最佳实践

  1. 保持测试独立:每个测试应该独立于其他测试,不依赖执行顺序。

  2. 使用有意义的测试名称:测试名称应该清晰描述被测试的功能。

  3. 测试错误情况:不仅要测试正常情况,还要测试错误和边界情况。

  4. 避免睡眠:在测试中避免使用 time.Sleep,使用同步机制或测试助手函数。

  5. 并行化长时间测试:对于长时间运行的测试,使用 t.Parallel() 来加速测试执行。

  6. 定期检查测试覆盖率:使用覆盖率工具确保测试足够全面。

  7. 保持测试快速:测试应该快速执行,以便频繁运行。

通过掌握 go test 的各种特性和技巧,您可以构建健壮、可维护的测试套件,确保代码质量并促进持续集成流程。

http://www.dtcms.com/a/410640.html

相关文章:

  • apifox认证登录自动化
  • 江西网站建设哪家专业女装wordpress
  • IDEA JVM优化配置idea64.vmoptions - 保守兼容版本 兼容IDEA 2023.3.6版本【亲测可用】
  • 网站图片像素多少做视频有赚钱的网站
  • APT攻击:隐蔽战场的威胁与防御之道
  • 小兔鲜项目
  • 黑马点评学习笔记01(手机号校验(正则表达式))
  • 声明式事务7
  • 外贸专业网站制作昆明建设网站哪家好
  • 鸿蒙原生contact.queryContacts通讯录查询实现
  • 根据百度地图做网站太原h5建站
  • 【JAVA】从入门到放弃-02-工具、类型、输入输出
  • 伪静态怎么设置(详细教程)
  • 【leetcode】57. 插入区间
  • 多sheet excel 导出
  • 手机移动端网站是什么用什么软件做网站布局
  • cesium-kit:让 Cesium 开发像写 UI 组件一样简单
  • 电子工程师网站wordpress the ken
  • Nginx HTTPS 深入实战 配置、性能与排查全流程(Nginx https
  • 网站建设和优化的营销话术亚马逊雨林生存游戏手机下载
  • 一场“无感换心”手术:金仓数据库如何让电子证照系统平滑告别MongoDB
  • 【开源】基于STM32的新疆地区棉花智能种植系统
  • 高平市规建设局网站短链接生成器
  • 解决SSL握手失败问题:SSLHandshakeException: Received fatal alert: handshake_failure
  • 降级版本Pillow解决freetypefont has no attribute getsize问题
  • 网站设计实例教程wordpress引用文章
  • 基于蜣螂优化的LSTM深度学习网络模型(DBO-LSTM)的一维时间序列预测算法matlab仿真
  • 改进的遗传算法优化的BP神经网络用于电厂数据的异常检测和故障诊断
  • 有什么公司要做推广的网站推广优化软件
  • visual studio 2019配置qt程序