当前位置: 代码网 > it编程>前端脚本>Golang > golang testing使用示例小结

golang testing使用示例小结

2024年05月26日 Golang 我要评论
testing包服务于自动化测试基本测试table drvien test基于表的测试通过表形式进行测试每种情况的输入和期望输出,从而测试程序的正确性func testfib(t *testing.t

testing包服务于自动化测试

基本测试

table drvien test

基于表的测试通过表形式进行测试每种情况的输入和期望输出,从而测试程序的正确性

func testfib(t *testing.t) {
    var fibtests = []struct {
        in       int // input
        expected int // expected result
    }{
        {1, 1},
        {2, 1},
        {3, 2},
        {4, 3},
        {5, 5},
        {6, 8},
        {7, 13},
    }
    for _, tt := range fibtests {
        actual := fib(tt.in)
        if actual != tt.expected {
            t.errorf("fib(%d) = %d; expected %d", tt.in, actual, tt.expected)
        }
    }
}
  • 跳过测试
    • skipnow(): 跳过测试
    • skip(): 跳过测试并输出log
    • skipf(): 跳过测试并格式化输出log
  • 失败但继续
    • fail(): 标记测试失败,但继续执行
    • failnow(): 标记测试失败,不继续执行
    • error(): 标记测试失败,并输出
    • errorf(): 标记测试失败,并格式化输出
  • 输出
    • log(): 输出
    • logf(): 格式化输出
  • 失败且中断
    • fatal(): 相当于failnow() + log()
    • fatalf(): 相当于failnow() + logf()

parallel()

parallel方法表示会和其他带有parallel方法的测试并行执行

examplexxx()

examplexxx方法中如果含有output: 开头的行注释,则会在运行测试期间,将输出和注释中的值相比较

如果是不确定的顺序,则可以以unordered output: 作为开头

但如果没有这样的注释,这就是一个普通函数,不能被直接运行

压力测试

压力测试方法以func benchmarkxxx(*testing.b)函数名展现。

函数体格式如下

func benchmarkhello(b *testing.b) {
    for i := 0; i < b.n; i++ {
        // do sth
    }
}

压力测试会自动调整b.n使得持续足够长时间

重置计时器

如果想要跳过不需要计时的耗时工作,那么可以通过b.resettimer()重置计时器

并行测试

如果想并行压力测试,那么可以通过runparallel实现

func benchmarkhelloparallel(b *testing.b) {
  b.runparallel(func(pb *testing.pb) {
    // do sth
  })
}

内存统计

reportallocs方法用于打开内存统计功能

输出结果就会变成如下形式

// 方法名        迭代总次数        平均每次迭代时间        平均每次迭代分配字节数        平均每次迭代的内存分配次数
benchmarkhello        2000000           898 ns/op         368 b/op           9 allocs/op

自定义度量值

reportmetric(n float64, unit string)汇报自定义度量值

  • 如果度量值是每次迭代的,你应该将其除以 b.n
  • 按照惯例,单位应该以 “/op” 结尾。
  • reportmetric 会覆盖同一单位的任何先前报告的值。如果单位是空字符串,或者单位包含任何空格,reportmetric 会引发 panic。
  • 如果单位是基准测试框架本身通常报告的单位(如 “allocs/op”),reportmetric 会覆盖该度量值。
  • 将 “ns/op” 设置为 0 将禁止该内置度量值。
testing.benchmark(func(b *testing.b) {
		var compares int64
		for i := 0; i < b.n; i++ {
			s := []int{5, 4, 3, 2, 1}
			sort.slice(s, func(i, j int) bool {
				compares++
				return s[i] < s[j]
			})
		}
		// this metric is per-operation, so divide by b.n and
		// report it as a "/op" unit.
		b.reportmetric(float64(compares)/float64(b.n), "compares/op")
		// this metric is per-time, so divide by b.elapsed and
		// report it as a "/ns" unit.
		b.reportmetric(float64(compares)/float64(b.elapsed().nanoseconds()), "compares/ns")
	})

子测试

子测试也就是可以在测试中测试,子测试可以共用初始化等公共操作,并可以做父测试执行前的必要操作

func testsubtest(t *testing.t) {
	t.run("sub1", func(t *testing.t) {
		t.log("sub1")
	})
	t.run("sub2", func(t *testing.t) {
		t.log("sub2")
	})
	t.run("sub3", func(t *testing.t) {
		t.log("sub3")
	})
}

模糊测试

模糊测试方法名为func fuzzxxx(f *testing.f)

func fuzzreverse(f *testing.f) {
  	// 为模糊测试添加用例到种子语料库
    testcases := []string{"hello, world", " ", "!12345"}
    for _, tc := range testcases {
        f.add(tc)  // use f.add to provide a seed corpus
    }
  	// 进行模糊测试。对于string类型的参数,将生成随机字符串
  	// 对于本测试中的reverse方法是可逆的,因此可以通过两次逆行操作来验证其正确性
    f.fuzz(func(t *testing.t, orig string) {
        rev := reverse(orig)
        doublerev := reverse(rev)
        if orig != doublerev {
            t.errorf("before: %q, after: %q", orig, doublerev)
        }
        if utf8.validstring(orig) && !utf8.validstring(rev) {
            t.errorf("reverse produced invalid utf-8 string %q", rev)
        }
    })
}

运行模糊测试有go testgo test -fuzz两种方式,前者仅会运行手动添加的用例,而后者则会随机生成数据

值得注意的是如果go test -fuzz执行之后存在运行错误的用例会添加到语料库文件中,那么即使下次执行的是go test也依然会执行语料库文件中的用例

ref

https://go.dev/doc/tutorial/fuzz

https://books.studygolang.com/the-golang-standard-library-by-example/chapter09/09.0.html

到此这篇关于golang testing使用的文章就介绍到这了,更多相关golang testing使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com