上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
12.3 模糊测试
又称随机测试,一种基于随机输入发现代码缺陷的自动化测试技术。
- 对单元测预定数据的补充,查找未预料错误。
- 并非验证逻辑正确,而是发现输入处理缺陷。
- 保存在
_test.go
内。 - 函数名以
Fuzz
为前缀。 - 类型
F
和T
方法类似,省略。
- 初始数据,称作 种子语料 (seed corpus)。
- 基于种子构造的随机数据,称作 随机语料 (random corpus)。
func FuzzAdd(f *testing.F) { // 添加种子。(可选) f.Add(1, 1) f.Add(1, 2) f.Add(1, 3) // 随机测试。(第一参数为 *T,后续和测试目标函数相同) f.Fuzz(func(t *testing.T, x, y int) { add(x, y) }) }
默认被当作普通单元测试运行。测试数据就是种子,不会引入随机语料。
$ go test -v ./mylib === RUN FuzzAdd === RUN FuzzAdd/seed#0 === RUN FuzzAdd/seed#1 === RUN FuzzAdd/seed#2 --- PASS: FuzzAdd (0.01s) --- PASS: FuzzAdd/seed#0 (0.00s) --- PASS: FuzzAdd/seed#1 (0.00s) --- PASS: FuzzAdd/seed#2 (0.00s) PASS ok test/mylib 0.011s
只有添加 -fuzz
参数才会进行随机测试。
默认无限期执行,直到失败或被用户中断( CTRL + C
)。
-fuzz
: 测试目标。(regex)-fuzztime
: 时长或次数。(1m20s
,100x
)
$ go test -v -fuzz Add -fuzztime 20s ./mylib === FUZZ FuzzAdd fuzz: elapsed: 0s, gathering baseline coverage: 0/3 completed fuzz: elapsed: 0s, gathering baseline coverage: 3/3 completed, 2 workers fuzz: elapsed: 3s, execs: 28786 (9594/sec), new interesting: 0 (total: 3) fuzz: elapsed: 6s, execs: 62406 (11205/sec), new interesting: 0 (total: 3) fuzz: elapsed: 9s, execs: 93140 (10245/sec), new interesting: 0 (total: 3) fuzz: elapsed: 12s, execs: 125159 (10671/sec), new interesting: 0 (total: 3) fuzz: elapsed: 15s, execs: 158390 (11079/sec), new interesting: 0 (total: 3) fuzz: elapsed: 18s, execs: 191887 (11164/sec), new interesting: 0 (total: 3) fuzz: elapsed: 20s, execs: 214470 (10858/sec), new interesting: 0 (total: 3) --- PASS: FuzzAdd (20.09s) PASS ok test/mylib 20.092s
模糊测试基于 “覆盖引导”(coverage guidance)。
start with some (potentially empty) corpus of inputs for { choose a random input from the corpus mutate the input execute the mutated input and collect code coverage if the input gives new coverage, add it to the corpus }
基线覆盖率(baseline coverage)是对现有语料(种子等)的测试结果,提供基准指标。
执行期间,如某条随机输入导致语料库之外的覆盖率变化,那么可称作 “new interesting”。
"
new interesting
" 保存在GOCACHE/fuzz
目录下,可被go clean -fuzzcache
清除。
elapsed
:启动时间。execs
:模糊输入总数。new interesting
:引发覆盖率变化的输入数,以及语料库总数。
引发失败的原因:
panic
t.Fail
...os.Exit
, stack overflow ...- 目标执行时间过长(默认 1 秒)。
语料库
除在代码中添加种子外,还可以将其存储在文件内,自动载入。
- 路径 :
testdata/fuzz/<FuzzName>/
- 文件 :每个文件保存一组语料,也就是一次
Add
调用的参数。
$ cat mylib/testdata/fuzz/FuzzAdd/a go test fuzz v1 int(1) int(1) $ cat mylib/testdata/fuzz/FuzzAdd/b go test fuzz v1 int(1) int(2) $ cat mylib/testdata/fuzz/FuzzAdd/c go test fuzz v1 int(1) int(3)
测试出错时,也会将随机输入存储到该路径下。
作为回归测试的基准语料,以检查目标是否被修复。
Failing input written to testdata/fuzz/FuzzAdd/3cb146f923...828c To re-run: go test -run=FuzzAdd/3cb146f923...828c
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论