Go 1.18 新增三大功能之一“模糊測試”使用方式
?1、介紹
在 Go 1.18 之前,Go 語言支持功能測試、基準測試和示例測試,在 Go 項目開發(fā)中,使用最多的是功能測試,讀者朋友們應該都比較熟悉功能測試的使用方式了。
在 Go 1.18 中,Go 語言新增模糊測試,本文我們介紹模糊測試的使用方式。
2、使用方式
Go 語言的模糊測試,與其他三種測試方式相同,測試文件的文件名以 _test.go? 結尾,測試文件中必須導入 testing 包。
模糊測試與其他三種測試方式的不同點是,函數(shù)名和函數(shù)簽名不同。
我們在之前關于 Go 測試的文章中介紹過,功能測試的函數(shù)名以 Test? 開頭,函數(shù)簽名是 t testing.T。
性能測試的函數(shù)名以 Benchmark? 開頭,函數(shù)簽名是 b testing.B。
模糊測試的函數(shù)名以 Fuzz? 開頭,函數(shù)簽名是 f testing.F。
與功能測試和性能測試相同,運行模糊測試也是使用 go test? 命令,讀者朋友們可以運行 go help test?或 go help testflag 了解更多。
3、模糊測試示例
Go 語言功能測試需要我們預定義測試值和與之對應的期望得到的值,如果測試輸出結果值與預先定義的期望值相同,則認為通過測試,反之,則認為未通過測試。
示例代碼:
功能測試代碼:
閱讀上面這段代碼,我們定義一個反轉字符串的函數(shù) Reverse?,并定義一個功能測試函數(shù) TestReverse,讀者朋友們應該非常熟悉類似的功能測試代碼。
但是,在實際項目開發(fā)中,我們很難考慮到所有測試用例,比如上面這段代碼運行結果是通過測試,我們一般就會認為定義的反轉字符串函數(shù) Reverse 功能正常。
實際結果并非如此,我們在測試用例中加入一組中文字符串,{"我愛學編程", "程編學愛我"},,我們再運行功能測試代碼,得到的結果就是未通過。
聰明的讀者朋友們,應該已經(jīng)發(fā)現(xiàn)問題在哪,修復該問題也很簡單,只需將 []byte? 改為 []rune,當然,這不是本文的重點,我們也就不深入解釋問題的原因了。
模糊測試,就是 Go 自動為我們的代碼提供輸入的測試用例,并可以測出相比我們自己提供測試用例所考慮不到的邊緣情況。
模糊測試代碼:
閱讀上面這段代碼,我們將功能測試代碼轉換為模糊測試代碼,仔細分析這段代碼,我們可以發(fā)現(xiàn),我們將功能測試中的輸入測試用例,通過 f.Add 將其作為模糊測是的種子語料庫。
在功能測試代碼的函數(shù)簽名中,新增一個字符串類型的參數(shù) orig?,將 orig? 原值經(jīng)過兩次反轉,如果最終結果與 orig? 不同,則為未通過測試,并將該代碼作為 f.Fuzz? 的參數(shù),這里的 orig 稱為模糊參數(shù)。
需要注意的是,運行模糊測試函數(shù)時,首次先不要使用 -fuzz,以確保種子輸入可以通過。
然后,在運行 go test -fuzz=Fuzz(也可以使用完整模糊測試函數(shù)名),運行失敗時,將導致運行失敗的輸入寫入種子語料庫。
接著,就是調式代碼,直到通過模糊測試,限于篇幅,我們不講述調試過程。
需要注意的時,當模糊測試可以通過時,模糊測試將一直運行,我們需要使用 ctrl-C? 結束程序。或者使用 -fuzztime 30s,代表如果模糊測試通過,運行 30s 將自動停止。
4、總結
本文我們介紹 Go 模糊測試的使用方式,它可以很好地解決功能測試無法考慮到所有邊界問題的情況。
關于模糊測是的更多內容,感興趣的讀者朋友們可以閱讀官方教程。