go testing

package testing

  • testing 提供对 Go 包的自动化测试的支持。通过 go test 命令,能够自动执行如下形式的任何函数
    要编写一个新的测试套件,需要创建一个名称以 _test.go 结尾的文件,该文件包含 TestXxx 函数,如上所述。
    将该文件放在与被测试的包相同的包中。该文件将被排除在正常的程序包之外,但在运行 “go test” 命令时将被包含。
    go test 带参的常用参数有:
    • -bench regexp 执行相应的 benchmarks,例如 -bench=.;
    • -cover 开启测试覆盖率;
    • -run regexp 只运行 regexp 匹配的函数,例如 -run=Array 那么就执行包含有 Array 开头的函数;
    • -v 显示测试的详细命令。
    • -benchmem: 对内存进行分析
    • -memprofile:指定内存分析的结果文件为memprofile.out
    • -cpuprofile:指定cpu分析的结果文件为profile.out
    • -o 参数指定生成的二进制可执行程序,并执行测试,测试结束不会删除该程序。
    • -cpu 参数提供一个CPU个数的列表,提供此列表后,那么测试将按照这个列表指定的CPU数设置GOMAXPROCS并分别测试。
    • -count 指定每个测试执行的次数,默认执行一次。
    • -timeout 测试超时退出,默认情况下,测试执行超过10分钟就会超时而退出。
命令使用
    go test -v -cpuprofile cpu.out -memprofile mem.out  // 测试生成内存和cpu文件

pprof生成文件分析

go tool pprof -http :8080 profile.out # 获取CPU文件分析结果
通过 http://localhost:8081/ui/ 访问网页

go tool pprof -http=":8081" memprofile.out # 分析内存

更多详细参数查看:go help testflag


类型 格式 作用
测试函数 函数名前缀为Test 测试程序的一些逻辑行为是否正确
基准函数 函数名前缀为Benchmark 测试函数的性能
示例函数 函数名前缀为Example 为文档提供示例文档
func TestXxx(*testing.T){}
func BenchmarkXxx(*testing.B){}
func ExampleXxxx(){}
其中 Xxx 可以是任何字母数字字符串(但第一个字母不能是 [a-z]),用于识别测试例程。

Example

vim hello_test.go

package main
import "testing"

# Test
func TestHello(t *testing.T) {
    got := Abs(-1)
    if got != 1 {
        t.Errorf("Abs(-1) = %d; want 1", got)
    }
    // t.Fail(): 将当前测试标识为失败,但是仍继续执行该测试。
}
    
# Benchmark 
func BenchmarkHello(b *testing.B) {
     // 基准函数会运行目标代码 b.N 次。在基准执行期间,会调整 b.N 直到基准测试函数持续足够长的时间。
    for i := 0; i < b.N; i++ {
        fmt.Sprintf("hello")
    }
}

# Example 
该包还运行并验证示例代码。示例函数可以包括以 "Output:" 开头的行注释,并在运行测试时与函数的标准输出进行比较。 (比较时会忽略前导和尾随空格。)
func ExampleHello(){
      fmt.Println("hello")
      // Output: hello
}

Main

测试程序有时需要在测试之前或之后进行额外的设置(setup)或拆卸(teardown)。
有时, 测试还需要控制在主线程上运行的代码。为了支持这些和其他一些情况, 如果测试文件包含函数:

func TestMain(m *testing.M)

那么生成的测试将调用 TestMain(m),而不是直接运行测试。
TestMain 运行在主 goroutine 中, 可以在调用 m.Run 前后做任何设置和拆卸。应该使用 m.Run 的返回值作为参数调用 os.Exit。

Example:

go test 如果遇到了此函数,首先调用此函数
func TestMain(m *testing.M) {
	# call flag.Parse() here if TestMain uses flags
        # 如果 TestMain 使用了 flags,这里应该加上 flag.Parse()
	os.Exit(m.Run())  # 要继续接着执行其他测试,需要执行此语句,否则会直接执行完毕。
}

type T

T 是传递给测试函数的一种类型,它用于管理测试状态并支持格式化测试日志。测试日志会在执行测试的过程中不断累积, 并在测试完成时转储至标准输出。

当一个测试的测试函数返回时, 又或者当一个测试函数调用 FailNow 、 Fatal 、 Fatalf 、 SkipNow 、 Skip 或者 Skipf 中的任意一个时, 该测试即宣告结束。 跟 Parallel 方法一样, 以上提到的这些方法只能在运行测试函数的 goroutine 中调用。

至于其他报告方法, 比如 Log 以及 Error 的变种, 则可以在多个 goroutine 中同时进行调用。

type B

B 是传递给基准测试函数的一种类型,它用于管理基准测试的计时行为,并指示应该迭代地运行测试多少次。

一个基准测试在它的基准测试函数返回时,又或者在它的基准测试函数调用 FailNow、Fatal、Fatalf、SkipNow、Skip 或者 Skipf 中的任意一个方法时,测试即宣告结束。至于其他报告方法,比如 Log 和 Error 的变种,则可以在其他 goroutine 中同时进行调用。

扫描二维码关注公众号,回复: 15114789 查看本文章

跟单元测试一样,基准测试会在执行的过程中积累日志,并在测试完毕时将日志转储到标准错误。但跟单元测试不一样的是,为了避免基准测试的结果受到日志打印操作的影响,基准测试总是会把日志打印出来。

猜你喜欢

转载自blog.csdn.net/weixin_56766616/article/details/129955811