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