網頁

2022/2/1

Golang Fuzzing測試簡單範例

Go 1.18推出的Fuzzing簡單範例。


Fuzzing(模糊測試)是一種自動化測試技術,以持續且隨機地輸入參數來找出程式中的臭蟲及錯誤。和單元測試差別在於單元測試時的輸入參數是事先人為規劃好的,而Fuzzing的輸入參數是隨機產生。Fuzzing測試可有效地找出容易忽略的邊緣案例(edge cases)以此檢測程式錯誤及安全漏洞。


主程式

主程式main.goPlus()為受測函式。

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


沒有留言:

張貼留言