模糊测试入门 (Fuzzing)

单元测试只能测试你想到的情况,而模糊测试能帮你发现你没想到的边界情况。 1. 什么是模糊测试? 模糊测试 (Fuzzing) 是一种自动化测试技术,通过生成大量随机或半随机的输入数据来测试程序,寻找崩溃、panic、死循环等异常。 传统测试 vs 模糊测试: // 传统单元测试:测试已知的输入 func TestAdd(t *testing.T) { if Add(2, 3) != 5 { t.Error("2 + 3 should be 5") } } // 模糊测试:测试大量随机输入 func FuzzAdd(f *testing.F) { f.Fuzz(func(t *testing.T, a, b int) { result := Add(a, b) // 检查属性而不是具体值 if result < a && result < b { t.Errorf("Add(%d, %d) = %d, should be >= both", a, b, result) } }) } 2. 编写 Fuzz 测试 2.1 基础示例 假设我们有一个解析 URL 的函数: // url.go package myurl import ( "fmt" "strings" ) func ParseURL(rawURL string) (string, error) { if !strings.HasPrefix(rawURL, "http://") && !strings.HasPrefix(rawURL, "https://") { return "", fmt.Errorf("invalid protocol") } return rawURL, nil } 编写 Fuzz 测试: // url_test.go package myurl import ( "testing" ) func FuzzParseURL(f *testing.F) { // 添加种子语料库(可选) f.Add("http://example.com") f.Add("https://google.com") f.Add("ftp://invalid.com") // Fuzz 函数 f.Fuzz(func(t *testing.T, rawURL string) { result, err := ParseURL(rawURL) // 检查:不应该 panic // 检查:如果没有错误,结果应该等于输入 if err == nil && result != rawURL { t.Errorf("ParseURL(%q) = %q, want %q", rawURL, result, rawURL) } }) } 2.2 运行 Fuzz 测试 # 运行模糊测试(会一直运行直到发现问题或手动停止) go test -fuzz=FuzzParseURL # 限制运行时间 go test -fuzz=FuzzParseURL -fuzztime=30s # 限制迭代次数 go test -fuzz=FuzzParseURL -fuzztime=10000x 2.3 查看结果 如果发现问题,Go 会自动保存导致崩溃的输入: ...

2025-08-20 · 3 min · 512 words · Hank

GoLang教程——单元测试与基准测试

在 Go 语言中,测试不是“一等公民”,而是“超等公民”。Go 编译器自带了 go test 工具,标准库提供了 testing 包,这使得编写测试变得异常简单且规范。 本章将详细介绍: 1. 单元测试:如何编写基础测试用例。 2. 表格驱动测试:Go 社区推荐的最佳实践,如何用更少的代码覆盖更多的场景。 3. 基准测试 (Benchmark):如何科学地测量代码的性能。 1. 基础单元测试 Go 的测试文件必须以 _test.go 结尾,测试函数必须以 Test 开头。 假设我们要测试一个简单的加法函数(保存为 math.go): package math func Add(a, b int) int { return a + b } 对应的测试文件(保存为 math_test.go): package math import ( "testing" ) // 测试函数签名:func TestXxx(t *testing.T) func TestAdd(t *testing.T) { got := Add(1, 2) want := 3 if got != want { // t.Errorf 输出错误信息,测试继续执行 // t.Fatalf 输出错误信息,并立即终止当前测试函数 t.Errorf("Add(1, 2) = %d; want %d", got, want) } } ...

2025-02-19 · 2 min · 324 words · Hank