channel生成器单元测试
go test 命令,会自动读取源码目录下面名为 *_test.go 的文件,生成并运行测试用的可执行文件。
新建一个 repeat_test.go 的文件:
package main
import "testing"
func BenchmarkGeneric(b *testing.B) {
repeat := func(
done <- chan interface{},
values ...interface{},
)<-chan interface{}{
stringStream := make(chan interface{})
go func() {
defer close(stringStream)
for{
for _,v := range values {
select {
case <- done:
return
case stringStream<-v:
}
}
}
}()
return stringStream
}
token := func(
done <-chan interface{},
valueStream <-chan interface{},
num int,
) <-chan interface{}{
tokenStream := make(chan interface{})
go func() {
defer close(tokenStream)
for i := num;i > 0||i == -1;{
if i != -1{
i--
}
select {
case <-done:
return
case tokenStream<-<-valueStream:
}
}
}()
return tokenStream
}
toString := func(
done <-chan interface{},
valueStream <-chan interface{},
) <- chan string{
stringStream := make(chan string)
go func() {
defer close(stringStream)
for v := range valueStream{
select {
case <-done:
return
case stringStream<-v.(string):
}
}
}()
return stringStream
}
done := make(chan interface{})
defer close(done)
b.ResetTimer()
for range toString(done,token(done,repeat(done,"a"),b.N)){
}
}
func BenchmarkTyped(b *testing.B){
repeat := func(
done <-chan interface{},
values ...string,
) <-chan string {
valueStream := make(chan string)
go func() {
defer close(valueStream)
for {
for _,v := range values{
select {
case <-done:
return
case valueStream<-v:
}
}
}
}()
return valueStream
}
take := func(
done <-chan interface{},
valueStream <-chan string,
num int,
)<-chan string {
takeStream := make(chan string)
go func() {
defer close(takeStream)
for i:=num;i>0||i == -1; {
if i != -1{
i--
}
select {
case <-done:
return
case takeStream<-<-valueStream:
}
}
}()
return takeStream
}
done := make(chan interface{})
defer close(done)
b.ResetTimer()
for range take(done,repeat(done,"a"),b.N) {
}
}
运行测试
# 测试所有函数
[root@izj6c4jirdug8kh3uo6rdez goroutine]# go test -v -bench=. -benchmem repeat_test.go
goos: linux
goarch: amd64
BenchmarkGeneric 1000000 1245 ns/op 0 B/op 0 allocs/op
BenchmarkTyped 2000000 793 ns/op 0 B/op 0 allocs/op
PASS
ok command-line-arguments 3.662s
# 测试 BenchmarkTyped 函数
[root@izj6c4jirdug8kh3uo6rdez goroutine]# go test -v -bench=Typed -benchmem repeat_test.go
goos: linux
goarch: amd64
BenchmarkTyped 2000000 762 ns/op 0 B/op 0 allocs/op
PASS
ok command-line-arguments 2.301s
----------------------------------
go test 命令常用的参数:
-bench regexp 执行相应的 benchmarks,例如 -bench=.
-cover 开启测试覆盖率
-run regexp 只运行 regexp 匹配的函数,例如 -run=Array 那么就执行包含有 Array 开头的函数
-v 显示测试的详细命令
注意:Windows 下使用 go test 命令行时,-bench=.应写为-bench="."。
-----------------------------------
go test 结果:
$ go test -v -bench=. -benchmem benchmark_test.go
----------------------------------------------------
goos: linux
goarch: amd64
Benchmark_Add-4 20000000 0.33 ns/op 16 B/op 2 allocs/op
PASS
ok command-line-arguments 0.700s
------------------------------------------------------
第 4 行中显示基准测试名称,
2000000000 表示测试的次数,也就是 testing.B 结构中提供给程序使用的 N。
0.33 ns/op 表示每一个操作耗费多少时间(纳秒)。
16 B/op 表示每一次调用需要分配 16 个字节,
2 allocs/op 表示每一次调用有两次分配。
第 5 行中
0.700s 表示程序运行花费的时间