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模糊测试的资料请关注脚本之家其它相关文章!

相关文章

  • 一文带你了解Go语言中函数设计的实践示例

    一文带你了解Go语言中函数设计的实践示例

    良好设计的函数具有清晰的职责和逻辑结构,提供准确的命名和适当的参数控制,下面我们将一一描述函数设计时能够遵循的最佳实践,希望对大家有所帮助
    2023-06-06
  • Go实现跨平台的蓝牙聊天室示例详解

    Go实现跨平台的蓝牙聊天室示例详解

    这篇文章主要为大家介绍了Go实现跨平台的蓝牙聊天室示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • go中Excelize处理excel表实现带数据校验的文件导出

    go中Excelize处理excel表实现带数据校验的文件导出

    本文主要介绍了go中Excelize处理excel表实现带数据校验的文件导出,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Golang设计模式之适配器模式详细讲解

    Golang设计模式之适配器模式详细讲解

    这篇文章主要介绍了使用go实现适配器模式,这个模式就是用来做适配的,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作,需要的朋友可以参考下
    2023-01-01
  • 详解玩转直播系列之消息模块演进

    详解玩转直播系列之消息模块演进

    本篇文章针对秀场直播,简单地描述一下消息模型,说明一下我们消息模型的架构,并结合我们一年以来,通过处理不同的业务线上问题,来进行演进式的消息模型架构的升级与调整,将此整理成文,并分享給大家
    2021-06-06
  • Go 语言中关于接口的三个

    Go 语言中关于接口的三个

    这篇文章主要介绍了Go 语言中关于接口的三个"潜规则",本文通过实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 详解golang的切片扩容机制

    详解golang的切片扩容机制

    golang的切片扩容机制是golang面试者绕不开的一扇大门,无论在面试提问,或者面试情景上都绕不开它,今天就说说我理解下的切片扩容机制,感兴趣的小伙伴跟着小编一起来看看吧
    2023-07-07
  • go语言使用io和bufio包进行流操作示例详解

    go语言使用io和bufio包进行流操作示例详解

    这篇文章主要为大家介绍了go语言使用io和bufio包进行流操作示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Gorm存在时更新,不存在时创建的问题

    Gorm存在时更新,不存在时创建的问题

    这篇文章主要介绍了Gorm存在时更新,不存在时创建的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 关于Golang中for-loop与goroutine的问题详解

    关于Golang中for-loop与goroutine的问题详解

    这篇文章主要给大家介绍了关于Golang中for-loop与goroutine问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用golang具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09

最新评论