Go中的fuzz模糊测试使用实战详解

 更新时间:2023年12月22日 10:27:53   作者:Go学习日记  
这篇文章主要为大家介绍了Go中的fuzz模糊测试使用实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

软件系统越复杂,测试就越重要。然而手动测试可能会非常费时和乏味。这就是为什么自动化测试变的越来越流行的原因。今天我们来聊一聊自动化测试中的一种测试技术就是fuzz测试,它是一种随机测试技术,可以帮助发现软件系统中的漏洞和错误。

Go语言目前已经是非常流行的语言了,具有高效、并发等特性。今天我们浅谈使用Go语言进行fuzz测试。从Go1.18开始,Go在其标准工具链中支持模糊测试。

什么是fuzz测试

模糊测试 (fuzz testing, fuzzing)是一种软件测试技术。其核心思想是将自动或半自动生成的随机数据输入到一个程序中,并监视程序异常,如崩溃,断言(assertion)失败,以发现可能的程序错误,比如内存泄漏。模糊测试常常用于检测软件或计算机系统的安全漏洞。

Go语言中的模糊测试

Go为开发者提供了一套强大的工具,用于实施模糊测试,核心是testing包中的Fuzz函数。通过创建以Fuzz为前缀的函数,按特定的签名定义输入输出,可以很容易集成模糊测试到我们的Go程序中。

上图是一个模糊测试的例子,突出显示了它的主要组件。

模糊测试必须要遵循的规则:

  • Fuzz测试必须是一个函数,函数名必须以"Fuzz"开头,后面必须是一个大写字母开头的名称,例如"FuzzAdd"。

  • Fuzz测试函数必须接受一个*testing.F类型的参数,不能有返回值。

  • Fuzz测试函数必须在*_test.go文件中定义才能运行。

  • Fuzz目标必须是一个方法调用,第一个参数必须是*testing.F类型,后面跟随着fuzz测试的参数。

  • 每个fuzz测试函数只能有一个fuzz目标。

  • 所有的种子语料库条目的类型必须与fuzz测试的参数类型相同,顺序也必须相同。这适用于对Fuzz函数的调用以及fuzz测试的testdata/fuzz目录中的任何语料库文件。

Fuzz测试的参数类型只能是以下类型:

string, []byte

int, uint, uintptr, int8, int16, int32, rune, int64, uint8, uint16, uint32, uint64

float32, float64

bool

这些规则和要求是Go语言fuzz测试的基本要求,遵循这些规则可以帮助我们编写有效的fuzz测试并提高测试覆盖率。

接下来我们通过一些简单代码来体验一下Fuzz test。

代码编写

我们创建一个名为fuzz的目录

> mkdir fuzz
> cd fuzz
> go mod init example/fuzz
> touch main.go

在main.go中我们贴如以下代码

package main
import "fmt"
func Add(a, b int) int {
  	return a + b
}
func main(){
  	fmt.Printf("Add(1, 2) = %d\n", Add(1, 2))
}

运行代码

go run .
Add(1, 2) = 3

现在代码正常运行,接下来我们来测试它。

添加单元测试

我们先为Add函数编写一个基本的单元测试。

  • fuzz目录创建一个文件为add_test.go

贴如以下代码到add_test.go

package main
import "testing"
func TestAdd(t *testing.T) {
	testcases := []struct {
		a, b, want int
	}{
		{1, 2, 3},
		{0, 0, 0},
		{-1, -2, -3},
		{1, -2, -1},
	}
	for _, tc := range testcases {
		got := Add(tc.a, tc.b)
		if got != tc.want {
			t.Errorf("Add(%d, %d) == %d, want %d", tc.a, tc.b, got, tc.want)
		}
	}
}

执行单元测试

> go test -v

=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
PASS
ok      example/fuzz    0.003s

添加模糊测试

单元测试的局限是我们必须把每个输入添加到测试中,模糊测试的好处是它提供了你的代码,并且可能识别你想出的测试用例的边缘情况。

我们把add_test.go中的单元测试替换为以下内容模糊测试。

func FuzzAdd(f *testing.F) {
	f.Add(1, 2)
	f.Add(0, 0)
	f.Add(-1, -2)
	f.Add(-2, -2)
	f.Fuzz(func(t *testing.T, a, b int) {
		got := Add(a, b)
		if got != a+b {
			t.Errorf("Add(%d, %d) == %d, want %d", a, b, got, a+b)
		}
		t.Logf("Add(%d, %d) == %d", a, b, got)
	})
}

接下来我们执行模糊测试, 通过-run选项用于指定要运行的测试函数的正则表达式,-fuzz选项用于指定要运行的fuzz测试函数的正则表达式,-fuzztime选项来控制fuzz测试的持续时间。

> go test -v -run=FuzzAdd -fuzz=Fuzz -fuzztime 10s
=== RUN   FuzzAdd
fuzz: elapsed: 0s, gathering baseline coverage: 0/11 completed
fuzz: elapsed: 0s, gathering baseline coverage: 11/11 completed, now fuzzing with 8 workers
fuzz: elapsed: 3s, execs: 718882 (239620/sec), new interesting: 1 (total: 12)
fuzz: elapsed: 6s, execs: 1444761 (241916/sec), new interesting: 1 (total: 12)
fuzz: elapsed: 9s, execs: 2177414 (244215/sec), new interesting: 1 (total: 12)
fuzz: elapsed: 10s, execs: 2415524 (216791/sec), new interesting: 1 (total: 12)
--- PASS: FuzzAdd (10.10s)
=== NAME  
PASS
ok      example/fuzz    10.106s

总的来说,Go语言内置的fuzz测试框架提供了一种方便的方式来进行fuzz测试,它与testing包紧密集成,可以更方便的进行单元测试和fuzz测试。

以上就是Go中的fuzz模糊测试使用实战详解的详细内容,更多关于Go fuzz模糊测试的资料请关注脚本之家其它相关文章!

相关文章

  • golang实现浏览器导出excel文件功能

    golang实现浏览器导出excel文件功能

    这篇文章主要介绍了golang实现浏览器导出excel文件功能,文章通过golang导出excel文件返回给web,实现浏览器导出excel文件功能,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-03-03
  • 使用Golang读取toml配置文件的代码实现

    使用Golang读取toml配置文件的代码实现

    在开发过程中,配置文件是必不可少的一部分,它使我们能够在不更改代码的情况下更改应用程序的行为,TOML是一种简单易读的配置文件格式,本文将介绍如何使用Golang来读取TOML配置文件,需要的朋友可以参考下
    2024-04-04
  • 使用Golang采集Nginx接口流量大小的步骤

    使用Golang采集Nginx接口流量大小的步骤

    在开发和运维中,我们经常需要监控和分析服务器的接口流量大小,特别是对于部署了 Nginx 的服务器,本文将介绍如何使用 Golang 采集 Nginx 接口流量大小,并展示如何将这些数据进行实时监控和分析
    2023-11-11
  • Golang 如何实现函数的任意类型传参

    Golang 如何实现函数的任意类型传参

    这篇文章主要介绍了Golang 实现函数的任意类型传参操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Go tablewriter库提升命令行输出专业度实例详解

    Go tablewriter库提升命令行输出专业度实例详解

    命令行工具大家都用过,如果是运维人员可能会编写命令行工具来完成各种任务,命令行输出的美观和易读性往往容易被忽视,很烂的输出会让人感觉不专业,本文将介绍Go语言中牛逼的实战工具tablewriter库,使你在命令行输出中展现出专业的一面
    2023-11-11
  • Golang Redis连接池实现原理及示例探究

    Golang Redis连接池实现原理及示例探究

    这篇文章主要为大家介绍了Golang Redis连接池实现示例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • GoLang channel使用介绍

    GoLang channel使用介绍

    Channel 和 goroutine 的结合是 Go 并发编程的大杀器。而 Channel 的实际应用也经常让人眼前一亮,通过与 select,cancel,timer 等结合,它能实现各种各样的功能。接下来,我们就要梳理一下 channel 的应用
    2022-10-10
  • Golang算法问题之数组按指定规则排序的方法分析

    Golang算法问题之数组按指定规则排序的方法分析

    这篇文章主要介绍了Golang算法问题之数组按指定规则排序的方法,结合实例形式分析了Go语言数组排序相关算法原理与操作技巧,需要的朋友可以参考下
    2017-02-02
  • Golang并发编程之调度器初始化详解

    Golang并发编程之调度器初始化详解

    这篇文章主要为大家详细介绍了Golang并发编程中关于调度器初始化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-03-03
  • Golang利用Recover进行错误处理

    Golang利用Recover进行错误处理

    Golang 中的 recover 是一个鲜为人知但非常有趣和强大的功能,这篇文章小编就来带大家深入了解一下在Golang中是如何利用Recover进行错误处理吧
    2023-12-12

最新评论