关于模糊测试和 Go 您需要了解的内容

Go 团队已接受一项关于向该语言添加模糊测试支持的提案。
31 位读者喜欢这篇文章。
Person using a laptop

Go 的使用正在快速增长。它现在是编写云原生软件、容器软件、命令行工具、数据库等的首选语言。Go 已经内置了 测试支持 很长一段时间了。它使得编写测试和使用 Go 工具运行它们相对容易。

什么是模糊测试?

模糊测试,有时也称为模糊测试技术,是指向您的软件提供意外输入的做法。理想情况下,此测试会导致您的应用程序崩溃或以意外方式运行。无论发生什么情况,您都可以从代码对未编程接受的数据的反应中学到很多东西,并且可以添加适当的错误处理。

任何给定的软件程序都包含接受来自各种来源的输入或数据的指令,然后它处理这些数据并生成适当的输出。随着软件的开发,测试工程师团队会测试该软件以查找软件中的错误,然后可以报告和修复这些错误。通常,目的是查看软件是否按预期运行。测试可以进一步分为多个领域,例如功能测试、集成测试、性能测试等等。每个领域都侧重于软件功能的特定方面,以查找错误或提高可靠性或性能。

模糊测试将此测试过程更进一步,并尝试向软件程序提供“无效”或“随机”数据。这是有意的,并且期望程序应该崩溃或表现异常,以发现程序中的错误,以便开发人员可以修复它们。与测试一样,手动执行此操作无法扩展,因此编写了许多模糊测试工具来自动化此过程。

Go 中的软件测试

作为测试 add.goAdd() 函数的示例,您可以在 add_test.go 中编写测试,方法是导入“testing”包并在以 TestXXX() 开头的函数中添加测试功能。

给定以下代码

func Add(num1, num2 int) int {
}

在一个名为 add_test.go 的文件中,您可能有以下用于测试的代码

import "testing"

func TestAdd(t *testing.T) {
}

运行测试

$ go test

添加模糊测试支持

Go 团队已接受一项 关于向该语言添加模糊测试支持 的提案,以进一步推进这项工作。这包括添加新的 testing.F 类型,在 _test.go 文件中添加 FuzzXXX() 函数,以及将使用 -fuzz 选项运行这些测试添加到 Go 工具中。

在一个名为 add_test.go 的文件中

func FuzzAdd(f *testing.F) {
}

运行代码

$ go test -fuzz

功能在撰写本文时是实验性的,但它应该包含在 1.18 版本中。此外,目前尚不支持 -keepfuzzing-race 等许多功能。Go 团队最近发布了 关于模糊测试的教程,非常值得一读。

使用 gotip 安装获取最新功能

如果您充满热情并希望在正式发布之前试用该功能,则可以使用 gotip,它允许您测试即将推出的 Go 功能并提供反馈。要安装 gotip,您可以使用以下命令。安装后,您可以使用 gotip 实用程序来编译和运行程序,而不是通常的 go 实用程序。

$ go install golang.org/dl/gotip@latest
$ gotip download


$ gotip version
go version devel go1.18-f009910 Thu Jan 6 16:22:21 2022 +0000 linux/amd64
$

社区中关于模糊测试的观点

模糊测试通常是软件社区讨论的焦点,我们发现人们对此褒贬不一。有些人认为它是一种查找错误(尤其是在安全方面)的有用技术。鉴于模糊测试所需的资源(CPU/内存),有些人认为这是一种浪费,或者更喜欢其他技术。这在 Go 团队中也很明显。我们可以看到 Go 联合创始人 Rob Pike 对模糊测试的用途及其在 Go 中的实现持轻微怀疑态度。

... 虽然模糊测试擅长查找某些类别的错误,但它在 CPU 和存储方面非常昂贵,并且成本/收益比仍然不明确。我担心浪费能源并用 testdata 噪声填充 git 仓库...

~Rob Pike

然而,Go 安全团队的另一位成员 Filo Sottile 似乎对在 Go 中添加模糊测试支持非常乐观,并用一些例子支持它,并希望它成为开发过程的一部分。

我喜欢说模糊测试可以发现边缘错误。这就是为什么我们作为安全团队对此感兴趣:在边缘捕获的错误是那些没有进入生产环境成为漏洞的错误。 

我们希望模糊测试成为开发过程(而不是构建或安全过程)的一部分:对相关代码进行更改...

~Filo Sottile

现实世界的模糊测试

对我而言,模糊测试在查找错误和使系统更安全和更具弹性方面似乎非常有效。举个例子,即使是 Linux 内核也使用名为 syzkaller 的工具进行模糊测试,并且它发现了 各种错误

AFL 是另一种流行的模糊器,用于模糊测试用 C/C++ 编写的程序。

过去也有可用于模糊测试 Go 程序的选项,其中之一是 go-fuzz,Filo 在他的 GitHub 评论中提到了它

go-fuzz 的记录提供了非常惊人的证据,表明模糊测试擅长查找人类尚未发现的错误。以我的经验,只需几分钟的 CPU 模糊测试就可以在边缘非常有效

为什么在 Go 中添加原生模糊测试支持

如果要求是模糊测试 Go 程序,并且像 go-fuzz 这样的现有工具可以做到这一点,那么为什么要在语言中添加原生模糊测试支持呢?Go 模糊测试设计草案 为这样做提供了一些理由。这个想法是为了简化流程,因为使用上述工具会给开发人员增加更多工作,并且缺少许多功能。如果您是模糊测试新手,我建议您阅读设计草案文档。

开发人员可以使用 go-fuzz 或 fzgo(构建在 go-fuzz 之上)等工具来解决他们的一些需求。但是,每个现有解决方案都比典型的 Go 测试涉及更多工作,并且缺少关键功能。模糊测试不应比其他类型的 Go 测试(如基准测试或单元测试)更复杂或功能更少。现有解决方案增加了额外的开销,例如自定义命令行工具,

模糊测试工具

模糊测试是 Go 语言长期以来渴望的功能列表中受欢迎的补充。虽然目前是实验性的,但预计在即将发布的版本中会变得更加强大。这为试用它并探索其用例提供了足够的时间。与其将其视为开销,不如将其视为一种有效的测试工具,如果使用得当,可以发现隐藏的错误。使用 Go 的团队应鼓励使用它,从开发人员编写小型模糊测试开始,测试团队进一步扩展它以充分利用其潜力。

接下来阅读什么
User profile image.
经验丰富的软件工程专业人士。主要兴趣是安全、Linux、恶意软件。喜欢在命令行上工作。对底层软件和了解事物的工作原理感兴趣。此处表达的观点仅代表我个人,不代表我的雇主

1 条评论

感谢您提供的精彩信息。

© . All rights reserved.