单元测试函数类型

Test(功能测试)

函数规则:

  • 函数名: TestXxxx , 以Test为前缀。Xxxx以大写字母开头
  • 参数类型: *testing.T
func TestXxxx(t *testing.T){...}

编写一个简单的例子,假设有下面一个待测函数:


func add(a, b int) int {
return a + b
}

测试代码如下:

import "testing"

func TestAdd(t *testing.T) {
cases := []struct {
first int
second int
excepted int
}{
{1, 2, 3},
{1, 2, 4},
} for _, c := range cases {
result := add(c.first, c.second)
if result != c.excepted {
t.Fatalf("add function failed, first: %d, second:%d, execpted:%d, result:%d", c.first, c.second, c.excepted, result)
}
}
}

执行 go go test -v 结果如下:

=== RUN   TestAdd
--- FAIL: TestAdd (0.00s)
example_test.go:30: add function failed, first: 1, second:2, execpted:4, result:3
FAIL
exit status 1
FAIL gotest/gotest 0.006s

第二个测试用例出错,未能通过单元测试,需要检查测试数据或者被测试函数是否符合我们的预期。

从上述过程可以看出, TestXxxx 可以理解为功能性测试,其目的在于测试函数的功能性是否正确, 应当编写尽可能多的测试用例来验证被测函数的正确性。

Benchmark(基准测试)

函数规则:

  • 函数名: BenchmarkXxxx, 以Benchmark为前缀。Xxxx以大写字母开头
  • 参数类型: *testing.B
func BenchmarkXxx(b *testing.B){...}

性能测试函数如下:

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

执行 go test -bench=. -run=^$,结果如下:

goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8 2000000000 0.32 ns/op
PASS
ok gotest/gotest 0.667s

测试结果说明:

  • -8 表示 8个逻辑cpu个数(下文会解释)
  • 2000000000 表示执行了 2000000000 次
  • 0.32 ns/op 每次操作耗时
  • 0.667s 是总时长

性能测试函数计时器:

当性能测试函数中有一些额外的初始化操作时,可以通过启停计时器来屏蔽这些操作对最终性能测试的影响。简单例子如下:

func BenchmarkAdd(b *testing.B) {
time.Sleep(10 * time.Second)
for i := 0; i < b.N; i++ {
add(1, 2)
}
}

执行命令go test -bench=.,结果如下:

goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8 1 10004479538 ns/op
PASS
ok gotest/gotest 10.011s

单个测试函数耗时为 10004479538 ns,同时我们也可以看到,这个函数执行一次就已经达到了最大上限时间。

加上时间计数器:

func BenchmarkAdd(b *testing.B) {
b.StopTimer()
time.Sleep(10 * time.Second)
b.StartTimer()
for i := 0; i < b.N; i++ {
add(1, 2)
}
}

测试结果如下:

goos: darwin
goarch: amd64
pkg: gotest/gotest
BenchmarkAdd-8 2000000000 0.34 ns/op
PASS
ok gotest/gotest 60.751s

单次执行耗时为: 0.34 ns 了。

Tips:

对于 b.N 参数而言, test 命令先会尝试设置为1,之后执行函数。如果测试函数没有达到执行上限的话, test 函数会增大,之后再次执行测试函数,如此往复,直到执行时间大于或者等于上限时间为止。 上限时间可以使用 -benchtime设定

Example(示例测试)

函数规则:

  • 函数名: ExampleXxx
  • 输出内容至标准输出,参数列表没有限制

示例测试函数如下:

func Println(content string) {
fmt.Println("The output of\nthis example.")
}
func ExamplePrintln() {
Println("The output of\nthis example.")
// Output: The output of
// this example.
}

go test 命令会检测实际输出与注释中的期望输出是否一致, 一致则测试通过,不一致则测试失败。

go test 常用参数

  • -cpu: 设置测试最大 cpu 逻辑数(也就是 GPM 中 P, 最大并行执行的 gorouting 数量, 默认等于 cpu 核数)
  • -count: 设置执行测试函数的次数, 默认为 1
  • -run: 执行功能测试函数, 支持正则匹配, 可以选择测试函数或者测试文件来仅测试单个函数或者单个文件
  • -bench: 执行基准测试函数, 支持正在匹配
  • -benchtime: 基准测试最大探索时间上限
  • -parallel: 设置同一个被测试代码包中的功能测试函数的最大并发执行数
  • -v: 是展示测试过程信息

更多的参数可以参考下文的官方文档

参考

golang 官方文档

极客时间

最新文章

  1. 对iOS10新增Api的详细探究
  2. sql where传入类型不同,造成查询结果差异问题
  3. Redis和Memcached的区别
  4. Linux 平台下 YUM 源配置 手册
  5. 定义页面的Dispose方法:[before]unload事件启示录
  6. C++重载赋值运算符
  7. spring security 配置多个AuthenticationProvider
  8. API网关系列之Kong的介绍以及安装
  9. Drupal7.8的安装注意的问题
  10. Struts2再爆远程命令执行漏洞![W3bSafe]Struts2-048 Poc Shell及防御修复方案抢先看!
  11. VMware网络桥接模式与NAT模式共存
  12. Docker 入门 之基本命令
  13. 刚刚明白了for循环写三角形
  14. linux显示桌面快捷键设置
  15. MySQL 数据库 分页查询
  16. ASP.NET WEBAPI设计(文摘)
  17. JavaScript的DOM_动态加载脚本和样式
  18. ethereumjs-vm/examples/run-transactions-simple
  19. C# 使用cmd
  20. Flask实战第61天:帖子板块过滤显示

热门文章

  1. Java学习笔记-文件读写和Json数组
  2. Linux服务器下日志截取
  3. MiniUI treeGrid 动态加载数据与静态加载数据的区别
  4. Docker容器(二)——镜像制作
  5. 123457123457#0#----com.DoraGame.ShiZi75--前拼后广--识字dora
  6. Spring Cloud Ribbon 客户端负载均衡 4.3
  7. intellij maven配置与使用
  8. git 操作说明
  9. C# 需要引用MySql.Data.dll,请在Nuget安装最新稳定版本,如果有版本兼容问题请先删除原有引用 (SqlSugar)
  10. 高级UI-SVG