Go 部落格

模糊測試 Beta 版已準備好

Katie Hockman 和 Jay Conrod
2021 年 6 月 3 日

我們很高興宣佈原生模糊測試已準備好針對 tip 進行 beta 測試!

模糊測試一種自動化測試,它會持續變更某一程式輸入值,以找出問題,例如恐慌或錯誤。這些半隨機資料突變會發現現有單元測試可能遺漏的新程式碼覆蓋範圍,並找出否則會未被注意的邊界狀況錯誤。由於模糊測試可以找出這些邊界狀況,因此模糊測試在找出安全漏洞及其弱點方面特別有價值。

請參閱 golang.org/s/draft-fuzzing-design,瞭解此功能的更多詳情。

開始

若要開始,您可以執行下列程式

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

這會從主分支建置 Go 工具鏈。執行此程式後,gotip 可作為 go 指令的立即替換品。現在您可以執行類似下列指令

$ gotip test -fuzz=Fuzz

撰寫模糊測試

模糊測試必須採用類似 FuzzXxx 形式的函式,並置於 *_test.go 檔案中。此函式必須傳遞一個 *testing.F 引數,跟傳遞 *testing.T 引數給 TestXxx 函式很類似。

以下是模糊測試範例,它會測試 net/url 套件 的行為。

//go:build go1.18
// +build go1.18

package fuzz

import (
    "net/url"
    "reflect"
    "testing"
)

func FuzzParseQuery(f *testing.F) {
    f.Add("x=1&y=2")
    f.Fuzz(func(t *testing.T, queryStr string) {
        query, err := url.ParseQuery(queryStr)
        if err != nil {
            t.Skip()
        }
        queryStr2 := query.Encode()
        query2, err := url.ParseQuery(queryStr2)
        if err != nil {
            t.Fatalf("ParseQuery failed to decode a valid encoded query %s: %v", queryStr2, err)
        }
        if !reflect.DeepEqual(query, query2) {
            t.Errorf("ParseQuery gave different query after being encoded\nbefore: %v\nafter: %v", query, query2)
        }
    })
}

您可以在 pkg.go.dev 進一步了解模糊測試,包含 使用 Go 進行模糊測試的概觀,以及 新的 testing.F 類型的 godoc

預期

這是仍在測試階段的新功能,因此您可能會遇到一些錯誤和功能組不完整的狀況。檢閱 標記為「模糊」的議題追蹤器,以掌握現有錯誤和遺失功能的最新動態。

請注意,模糊測試可能會耗用大量記憶體,並在執行期間影響電腦效能。go test -fuzz 預設會以平行方式在 $GOMAXPROCS 程序中進行模糊測試。您可以使用 go test 搭配 -parallel 旗標明確定義進程數量,以減少模糊測試使用的程序數量。如果您需要更多資訊,請執行 gotip help testflag 閱讀 go test 命令文件。

此外,請注意模糊測試引擎會在 $GOCACHE/fuzz 中的模糊快取目錄寫入可擴充測試範圍的值。目前對於模糊快取中寫入的檔案數量或總位元組數並無限制,因此它可能會佔用大量儲存空間 (例如,數 GB)。您可以執行 gotip clean -fuzzcache 來清除模糊快取。

下一步

這項功能將在 Go 1.18 起可用。

如果您遇到任何問題或對功能有任何建議,請 提交問題

對於有關這項功能的討論和一般回饋,您也可以參與 Gophers Slack 上的 #fuzzing 頻道

盡情模糊測試!

下一篇文章:Stack Overflow 上的 Go Collective
上一篇文章:2020 年 Go 開發者調查結果
部落格索引