Go 1.18 新增三大功能之一“模糊测试”使用方式

简介: Go 1.18 新增三大功能之一“模糊测试”使用方式

介绍

在 Go 1.18 之前,Go 语言支持功能测试、基准测试和示例测试,在 Go 项目开发中,使用最多的是功能测试,读者朋友们应该都比较熟悉功能测试的使用方式了。

在 Go 1.18 中,Go 语言新增模糊测试,本文我们介绍模糊测试的使用方式。

使用方式

Go 语言的模糊测试,与其他三种测试方式相同,测试文件的文件名以 _test.go 结尾,测试文件中必须导入 testing 包。

模糊测试与其他三种测试方式的不同点是,函数名和函数签名不同。

我们在之前关于 Go 测试的文章中介绍过,功能测试的函数名以 Test 开头,函数签名是 t testing.T

性能测试的函数名以 Benchmark 开头,函数签名是 b testing.B

模糊测试的函数名以 Fuzz 开头,函数签名是 f testing.F

与功能测试和性能测试相同,运行模糊测试也是使用 go test 命令,读者朋友们可以运行 go help testgo help testflag 了解更多。

03

模糊测试示例

Go 语言功能测试需要我们预定义测试值和与之对应的期望得到的值,如果测试输出结果值与预先定义的期望值相同,则认为通过测试,反之,则认为未通过测试。

示例代码:

func Reverse(s string) string {
 b := []byte(s)
 for i, j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1 {
  b[i], b[j] = b[j], b[i]
 }
 return string(b)
}

功能测试代码:

func TestReverse(t *testing.T) {
 testcases := []struct {
  in, want string
 }{
  {"Hello, world", "dlrow ,olleH"},
  {" ", " "},
  {"!12345", "54321!"},
 }
 for _, tc := range testcases {
  rev := Reverse(tc.in)
  if rev != tc.want {
   t.Errorf("Reverse: %q, want %q", rev, tc.want)
  }
 }
}

阅读上面这段代码,我们定义一个反转字符串的函数 Reverse,并定义一个功能测试函数 TestReverse,读者朋友们应该非常熟悉类似的功能测试代码。

但是,在实际项目开发中,我们很难考虑到所有测试用例,比如上面这段代码运行结果是通过测试,我们一般就会认为定义的反转字符串函数 Reverse 功能正常。

实际结果并非如此,我们在测试用例中加入一组中文字符串,{"我爱学编程", "程编学爱我"},,我们再运行功能测试代码,得到的结果就是未通过。

聪明的读者朋友们,应该已经发现问题在哪,修复该问题也很简单,只需将 []byte 改为 []rune,当然,这不是本文的重点,我们也就不深入解释问题的原因了。

模糊测试,就是 Go 自动为我们的代码提供输入的测试用例,并可以测出相比我们自己提供测试用例所考虑不到的边缘情况。

模糊测试代码:

func FuzzReverse(f *testing.F) {
 testcases := []string{"Hello, world", " ", "!12345"}
 for _, tc := range testcases {
  f.Add(tc) // Use f.Add to provide a seed corpus
 }
 f.Fuzz(func(t *testing.T, orig string) {
  rev := Reverse(orig)
  doubleRev := Reverse(rev)
  if orig != doubleRev {
   t.Errorf("Before: %q, after: %q", orig, doubleRev)
  }
 })
}

阅读上面这段代码,我们将功能测试代码转换为模糊测试代码,仔细分析这段代码,我们可以发现,我们将功能测试中的输入测试用例,通过 f.Add 将其作为模糊测是的种子语料库。

在功能测试代码的函数签名中,新增一个字符串类型的参数 orig,将 orig 原值经过两次反转,如果最终结果与 orig 不同,则为未通过测试,并将该代码作为 f.Fuzz 的参数,这里的 orig 称为模糊参数。

640.png

需要注意的是,运行模糊测试函数时,首次先不要使用 -fuzz,以确保种子输入可以通过。

然后,在运行 go test -fuzz=Fuzz(也可以使用完整模糊测试函数名),运行失败时,将导致运行失败的输入写入种子语料库。

接着,就是调式代码,直到通过模糊测试,限于篇幅,我们不讲述调试过程。

需要注意的时,当模糊测试可以通过时,模糊测试将一直运行,我们需要使用 ctrl-C 结束程序。或者使用 -fuzztime 30s,代表如果模糊测试通过,运行 30s 将自动停止。

04

总结

本文我们介绍 Go 模糊测试的使用方式,它可以很好地解决功能测试无法考虑到所有边界问题的情况。

关于模糊测是的更多内容,感兴趣的读者朋友们可以阅读官方教程。

推荐阅读:

参考资料:

  1. https://go.dev/doc/tutorial/fuzz
  2. https://go.dev/security/fuzz/


目录
相关文章
|
3月前
|
JSON 测试技术 API
Apipost与Apifox测试功能对决,谁更适合开发者?
在API开发中,调试工具的选择至关重要。本文对比了国产工具Apipost与Apifox的功能差异,涵盖调试能力、环境管理、团队协作、文档生成、自动化测试等方面。Apifox在细节处理、协作支持及生态集成上表现更优,适合复杂项目与团队开发;而Apipost则适合基础调试需求。通过全面评估,开发者可依据项目特点选择合适工具,提升开发效率与质量。
Apipost与Apifox测试功能对决,谁更适合开发者?
|
3月前
|
人工智能 测试技术 项目管理
测试不再碎片化:AI智能体平台「项目资料套件」功能上线!
在实际项目中,需求文档分散、整理费时、测试遗漏等问题常困扰测试工作。霍格沃兹推出AI智能体测试平台全新功能——项目资料套件,可将多个关联文档打包管理,并一键生成测试用例,提升测试完整性与效率。支持套件创建、文档关联、编辑删除及用例生成,适用于复杂项目、版本迭代等场景,助力实现智能化测试协作,让测试更高效、更专业。
|
3月前
|
存储 人工智能 测试技术
用AI提升测试效率:智能体平台的「需求文档管理」功能上线啦!
霍格沃兹测试开发学社推出AI智能体测试平台,全新「需求文档管理」功能助力高效测试准备。集中管理需求文档,支持多种上传方式,智能生成测试用例,提升测试效率与准确性,助力迈向智能化测试新时代。
|
4月前
|
人工智能 监控 中间件
如何用go语言实现类似AOP的功能
本文介绍了如何在 Go 语言中借鉴 Java 的 AOP(面向切面编程)思想,通过 Gin 框架的中间件和函数包装机制实现日志记录、权限校验等横切关注点与业务逻辑的解耦。内容涵盖 AOP 的优点、Go 中的实现方式、Gin 中间件与 AOP 的异同,帮助开发者提升代码模块化与可维护性。
164 0
|
3月前
|
人工智能 自然语言处理 前端开发
深度解析Playwright MCP:功能、优势与挑战,AI如何提升测试效率与覆盖率
Playwright MCP通过AI与浏览器交互,实现自然语言驱动的自动化测试。它降低门槛、提升效率,助力测试工程师聚焦高价值工作,是探索性测试与快速验证的新利器。
|
3月前
|
测试技术
自动化测试登录后的功能
在自动化测试的时候,往往许多功能需要登录以后才可以进行操作的,在这里我介绍一种方法,在登录以后将Cookies信息存入本地文件,在测试登录以后操作的时候再从本地文件把信息调出来存入Cookies
79 4
|
5月前
|
敏捷开发 运维 数据可视化
DevOps看板工具中的协作功能:如何打破开发、测试与运维之间的沟通壁垒
在DevOps实践中,看板工具通过可视化任务管理和自动化流程,提升开发与运维团队的协作效率。它支持敏捷开发、持续交付,助力团队高效应对需求变化,实现跨职能协作与流程优化。
|
6月前
|
测试技术 程序员 Go
Go语言测试简明指南:深度解读go test命令
总的来说,go test是 Go 语言中一个强而有力的工具,每个 Go 程序员都应该掌握并把它融入到日常的开发和调试过程中。就像是一个眼镜过滤出的太阳,让我们在宽阔的代码海洋中游泳,而不是淹没。用好它,让我们的代码更健壮,让我们的生产力更强效。
536 23
|
9月前
|
SQL 运维 监控
高效定位 Go 应用问题:Go 可观测性功能深度解析
为进一步赋能用户在复杂场景下快速定位与解决问题,我们结合近期发布的一系列全新功能,精心梳理了一套从接入到问题发现、再到问题排查与精准定位的最佳实践指南。
|
11月前
|
弹性计算 运维 Java
OS-Copilot参数功能全面测试报告
作为一名运维工程师,我主要负责云资源的运维和管理。通过使用OS Copilot的-t/-f/管道功能,我顺利解决了环境快速搭建的问题,例如Tomcat的快速部署。具体步骤包括购买ECS服务器、配置安全组、远程登录并安装OS Copilot。使用-f参数成功安装并启动Tomcat,自动配置JDK,并通过|管道功能验证了生成内容的正确性。整个过程非常流畅,极大提升了工作效率。
182 12