「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。
go1.18beta1支持了泛型(generic)、模糊测试(fuzzing)、工作空间模式(go workspace mode)
对模糊测试比较感兴趣,稍微了解一下,做个小demo。
安装go1.18beta2
复制以下指令
go install golang.org/dl/go1.18beta2@latest
go1.18beta2 download
编译运行时使用go1.18beta2命令即可
go1.18beta2 run xxx.go
模糊测试
go1.18版本将支持原生的模糊测试,现在推出的go1.18beta2是测试版本,抢先体验。
模糊测试(fuzz testing, fuzzing)是一种软件测试技术。 其核心思想是將自动或半自动生成的随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。 ———维基百科
随机数据测试可以测试出单元测试未覆盖到的代码。模糊测试可以检测到一些边界情况,对于寻找漏洞和脆弱代码有一定价值。
实践
在*_test 文件里起名为FuzzXxx函数。 该函数必须传入*testing.F 参数。
fuzzing可能会消耗大量内存,并可能在运行时影响到机器的性能。go test -fuzz默认使用$GOMAXPROCS个进程并行运行fuzzing。fuzzing引擎在运行时将扩展的测试覆盖值写入$GOCACHE/fuzz目录中,该文件作为缓存目录,目前没有限制可以写入模糊缓存的文件的数量或总字节数,所以它可能会占用大量的存储(通常是几个GB)
例子
下面这个例子是使用模糊测试,测试net/url包的行为。
//go:build go1.18
// +build go1.18
package fuzz
import (
"net/url"
"reflect"
"testing"
)
func FuzzParseQuery(f *testing.F) {
f.Add("x=1&y=2")
f.Fuzz(func(t *testing.T, queryStr string) {
query, err := url.ParseQuery(queryStr)
if err != nil {
t.Skip()
}
queryStr2 := query.Encode()
query2, err := url.ParseQuery(queryStr2)
if err != nil {
t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err)
}
if !reflect.DeepEqual(query, query2) {
t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2)
}
})
}
f.Add增加默认测试输入f.Fuzz函数的函数参数是模糊测试的目标- 被测函数必须传入*T参数以及一个或多个随机输入,例子程序中的随机输入参数是
queryStr fuzz将使用重复对默认输入(f.Add添加默认seed)进行随机更改而生成的参数来调用fuzzing引擎将导致失败的输入写入包目录中testdata/fuzz/<Name>目录中的一个文件,如下图
运行
go1.18beta2 test -fuzz=Fuzz .\fuzzing_test.go
结果
fuzz: elapsed: 0s, gathering baseline coverage: 0/1 completed
fuzz: elapsed: 0s, gathering baseline coverage: 1/1 completed, now fuzzing with 16 workers
fuzz: elapsed: 3s, execs: 737527 (245821/sec), new interesting: 156 (total: 156)
fuzz: elapsed: 6s, execs: 1659546 (307344/sec), new interesting: 178 (total: 178)
..................................................................................
总结
模糊测试可以检测到单元测试无法覆盖到的边界情况,Fuzz.Add(inputCase)函数中添加默认情况(Seed input),模糊测试时会更改默认输入数据,良好的Seed可以帮助模糊测试更好的检测到bug。模糊测试会使用到测试机器的内存和硬盘,会对机器性能有一定影响,使用时需要注意这一点。
参考翻译
Tutorial: Getting started with fuzzing - The Go Programming Language