文件名必须是_test.go结尾的,这样在执行go test的时候才会执行到相应的代码
你必须import testing这个包
所有的测试用例函数必须是Test开头
测试用例会按照源代码中写的顺序依次执行
测试函数TestXxx()的参数是testing.T,我们可以使用该类型来记录错误或者是测试状态
测试格式:func TestXxx (t *testing.T),Xxx部分可以为任意的字母数字的组合,但是首字母不
是小写字母[a-z],例如Testintdiv是错误的函数名。
函数中通过调用testing.T的Error, Errorf, FailNow, Fatal, FatalIf方法,说明测试不通过,调用Log方法用来记录测试的信息。
func TestCompareIdenticalSlice(t *testing.T) {
sa := "aaa"
sb := "bbb"
if strings.Compare(sa, sb) != 0 {
t.Error("b != b")
}
}
func TestCompareIdenticalSlice(t *testing.T) {
sa := "aaa"
sb := "bbb"
if strings.Compare(sa, sb) != 0 {
t.Fatal("error")
}
s1 := "aaa1"
s2 := "bbb"
if strings.Compare(s1, s2) != 0 {
t.Errorf("errorf")
}
}
func TestCompareIdenticalSlice(t *testing.T) {
sa := "aaa"
sb := "bbb"
if strings.Compare(sa, sb) != 0 {
t.Skip("slow test; skipping")
}
s1 := "aaa1"
s2 := "bbb"
if strings.Compare(s1, s2) != 0 {
t.Errorf("errorf")
}
}
func TestCompareIdenticalSlice1(t *testing.T) {
sa := "aaa"
sb := "bbb"
if strings.Compare(sa, sb) != 0 {
t.Errorf("errorf2")
}
s1 := "bbb"
s2 := "bbb"
if strings.Compare(s1, s2) != 0 {
t.Errorf("errorf2")
}
}
func gorw() {
sa := "aaa"
sb := "bbb"
if strings.Compare(sa, sb) != 0 {
fmt.Println("dfdf")
}
}
func TestCompareIdenticalSlice(t *testing.T) {
t.Parallel()
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
gorw()
}()
wg.Wait()
}
sync.WaitGroup只有3个方法,Add(),Done(),Wait()。其中Done()是Add(-1)的别名。简单的来说,使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行。
要注意的有一点。sync文档已经说明了的,The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished.也就是说,在运行main函数的goroutine里运行Add()函数,在其他的goroutine里面运行Done()函数。
性能测试函数需要接收*testing.B类型的单一参数b,性能测试函数中需要循环b.N次调用被测函数。testing.B 类型用来管理测试时间和迭代运行次数,也支持和testing.T相同的方式管理测试状态和格式化的测试日志,不一样的是testing.B的日志总是会输出。
func BenchmarkCompareIdenticalSlice(b *testing.B) {
b.ReportAllocs()
sa := "aaa"
sb := "bbb"
if strings.Compare(sa, sb) != 0 {
fmt.Println("dfdf")
}
}
func BenchmarkCompareIdenticalSlice(b *testing.B) {
b.ResetTimer()
b.StartTimer()
for i := b.N - 1; i >= 0; i-- {
fmt.Println(i)
}
b.StopTimer()
}
func BenchmarkCompareIdenticalSlice(b *testing.B) {
b.SetBytes(int64(len("fieldsInput")))
for i := 0; i < b.N; i++ {
fmt.Println("fieldsInput")
}
}
func BenchmarkCompareIdenticalSlice(b *testing.B) {
var v atomic.Value
v.Store(new(int))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
x := v.Load().(*int)
if *x != 0 {
b.Fatalf("wrong value: got %v, want 0", *x)
}
}
})
}
E:\GoWorks>go test -v
=== RUN TestCompareIdenticalSlice
--- FAIL: TestCompareIdenticalSlice (0.00s)
main_test.go:27: sa != sb
FAIL
exit status 1
FAIL _/E_/GoWorks 0.094s
E:\GoWorks>go test -v -run="TestCompareIdenticalSlice"
=== RUN TestCompareIdenticalSlice
--- FAIL: TestCompareIdenticalSlice (0.00s)
main_test.go:27: sa != sb
FAIL
exit status 1
FAIL _/E_/GoWorks 0.090s
(1) E:\GoWorks>go test -bench=.
BenchmarkCompareIdenticalSlice-8 1000000000 2.46 ns/op
PASS
ok _/E_/GoWorks 2.789s
(2) E:\GoWorks>go test -bench=BenchmarkCompareIdenticalSlice2
BenchmarkCompareIdenticalSlice2-8 1000000000 2.33 ns/op
PASS
ok _/E_/GoWorks 2.577s
E:\GoWorks>go test -bench="BenchmarkCompareIdenticalSlice2" -benchmem
BenchmarkCompareIdenticalSlice2-8 1000000000 2.47 ns/op 0 B/op 0 allocs/op
PASS
ok _/E_/GoWorks 2.800s
格式形如:
go test [-c] [-i] [build flags] [packages] [flags for test binary]
参数解读:
1. -c : 编译go test成为可执行的二进制文件,但是不运行测试。
2. -i : 安装测试包依赖的package,但是不运行测试。
关于build flags,调用go help build,这些是编译运行过程中需要使用到的参数,一般设置为空
关于packages,调用go help packages,这些是关于包的管理,一般设置为空
关于flags for test binary,调用go help testflag,这些是go test过程中经常使用到的参数
3. -test.v : 是否输出全部的单元测试用例(不管成功或者失败),默认没有加上,所以只输出失败的单元测试用例。
E:\GoWorks>go test -v
4 -test.run pattern: 只跑哪些单元测试用例 :
E:\GoWorks>go test -run="TestCompareIdenticalSlice"
5 -test.bench patten: 只跑那些性能测试用例
E:\GoWorks> go test -bench="."
6 -test.benchmem : 是否在性能测试的时候输出内存情况:
E:\GoWorks> go test -bench="BenchmarkCompareIdenticalSlice2" -benchmem
7 -test.benchtime t : 性能测试运行的时间,默认是1s
8 -test.cpuprofile cpu.out : 是否输出cpu性能分析文件
E:\GoWorks>go test -run = "main_test.go" -cpuprofile cpu.out
9 -test.memprofile mem.out : 是否输出内存性能分析文件
E:\GoWorks> go test -run = "main_test.go" -memprofile mem.out
10 -test.blockprofile block.out : 是否输出内部goroutine阻塞的性能分析文件
E:\GoWorks> go test -run = "main_test.go" -blockprofile mem.out
11 -test.memprofilerate n : 内存性能分析的时候有一个分配了多少的时候才打点记录的问题。这个参数就是设置打点的内存分配间隔,也就是profile中一个sample代表的内存大小。默认是设置为512 * 1024的。如果你将它设置为1,则每分配一个内存块就会在profile中有个打点,那么生成的profile的sample就会非常多。如果你设置为0,那就是不做打点了。
你可以通过设置memprofilerate=1和GOGC=off来关闭内存回收,并且对每个内存块的分配进行观察。
12 -test.blockprofilerate n: 基本同上,控制的是goroutine阻塞时候打点的纳秒数。默认不设置就相当于-test.blockprofilerate=1,每一纳秒都打点记录一下
13 -test.parallel n : 性能测试的程序并行cpu数,默认等于GOMAXPROCS。
14 -test.timeout t : 如果一个测试运行的时间超过t,那么panic。 默认值是10分钟(1000米)。
E:\GoWorks>go test -run="main_test.go" -timeout 1000s
15 -test.count n: 运行每个测试和基准测试n次(默认1)。 如果-cpu被设置,则为每个GOMAXPROCS值运行n次。 示例总是运行一次。
E:\GoWorks>go test -bench="BenchmarkCompareIdenticalSlice2" -count=10
16 -test.cpu 1,2,4 : 程序运行在哪些CPU上面,使用二进制的1所在位代表,和nginx的nginxworkercpu_affinity是一个道理
17 -test.short : 将那些运行时间较长的测试用例运行时间缩短
E:\GoWorks>go test -run="main_test.go" -short=false
18 -outputdir directory: 将输出文件从指定目录的概要文件中放置
E:\GoWorks>go test -bench="BenchmarkCompareIdenticalSlice2" -test.blockprofile block.out -outputdir="E:/GoWorks/data"
19 -trace trace.out : 关于执行跟踪向文件中写入指定在退出之前
E:\GoWorks>go test -bench="BenchmarkCompareIdenticalSlice2" -trace trace.out
20 -test.memprofilerate rate:设置内存分析率(见运行时)
21 -test.mutexprofile string:在执行后将一个互斥锁争用配置文件写入到指定的文件中
22 -test.mutexprofilefraction int :如果大于0,则调用runtime.setmutexprofile分式()