Go 1.18推出的Fuzzing簡單範例。
Fuzzing(模糊測試)是一種自動化測試技術,以持續且隨機地輸入參數來找出程式中的臭蟲及錯誤。和單元測試差別在於單元測試時的輸入參數是事先人為規劃好的,而Fuzzing的輸入參數是隨機產生。Fuzzing測試可有效地找出容易忽略的邊緣案例(edge cases)以此檢測程式錯誤及安全漏洞。
主程式
主程式main.go
的Plus()
為受測函式。
main.go
package main
import (
"fmt"
)
func main() {
fmt.Println(Plus(1, 2))
}
func Plus(x, y int) int {
return x + y
}
測試程式
測試程式的TestPlus()
為單元測試;FuzzPlus()
為fuzzing test。
Fuzzing測試函式名稱要求以Fuzz
開頭,參數為*testing.F
型態,無回傳值,與單元測試函式一樣放在_test.go
檔案。
調用(*testing.F).Add()
提供fuzzing參數的種子語料(seed corpus),參數順序型態同受測函式。
呼叫(*testing.F).Fuzz()
執行fuzzing測試,此為fuzzing target,其第一個參數為*testing.T
,後接多個符合受測函式參數順序的fuzzing參數(fuzzing arguments)。
Fuzzing參數只能是以下型別:
- string, []byte
- int, int8, int16, int32/rune, int64
- uint, uint8/byte, uint16, uint32, uint64
- float32, float64
- bool
main_test.go
package main
import (
"testing"
)
type testcase struct {
x int
y int
expected int
}
// Unit test
func TestPlus(t *testing.T) {
// Arrange
tc := testcase{2, 1, 3}
// Act
result := Plus(tc.x, tc.y)
// Assert
if result != tc.expected {
t.Errorf("expected %d, but %d", result, tc.expected)
}
}
// Fuzzing test
func FuzzPlus(f *testing.F) {
f.Add(2, 1) // provide a seed corpus
f.Fuzz(func(t *testing.T, x, y int) {
Plus(x, y)
})
}
執行Fuzzing測試
在專案根目錄以命令列輸入go test -fuzz=FuzzPlus -fuzztime 3s
執行fuzzing測試,單元測試會先執行,然後才執行fuzzing測試。-fuzz
代表執行fuzzing測試,後接要執行的fuzz測試函式名稱;-fuzztime
為執行的時間,範例3s
代表執行3秒後離開,若沒設定執行時間則預設會持續執行直到出錯。
~/../go-demo$ go test -fuzz=FuzzPlus -fuzztime 3s
沒有留言:
張貼留言