GoConvey是一款針對Golang的測試框架,能夠管理和運行測試用例,同時提供了豐富的斷言函數,並支持多種Web界面特性。
官方地址:
https://github.com/smartystreets/goconvey
安裝:go get github.com/smartystreets/goconvey
git
GoConvey支持 go test,可直接在終端窗口和瀏覽器上使用。GoConvey特色以下:
A、直接集成go test
B、巨大的迴歸測試套件
C、可讀性強的色彩控制檯輸出
D、徹底自動化的Web UI
E、測試代碼生成器github
官方文檔:
https://github.com/smartystreets/goconvey/wiki
GoConvey自帶大量的標準斷言函數,能夠經過So()使用。
(1)通用相等比較
So(thing1, ShouldEqual, thing2)
So(thing1, ShouldNotEqual, thing2)
So(thing1, ShouldResemble, thing2)
用於數組、切片、map和結構體的深度比較
So(thing1, ShouldNotResemble, thing2)
So(thing1, ShouldPointTo, thing2)
So(thing1, ShouldNotPointTo, thing2)
So(thing1, ShouldBeNil)
So(thing1, ShouldNotBeNil)
So(thing1, ShouldBeTrue)
So(thing1, ShouldBeFalse)
So(thing1, ShouldBeZeroValue)
(2)數值比較
So(1, ShouldBeGreaterThan, 0)
So(1, ShouldBeGreaterThanOrEqualTo, 0)
So(1, ShouldBeLessThan, 2)
So(1, ShouldBeLessThanOrEqualTo, 2)
So(1.1, ShouldBeBetween, .8, 1.2)
So(1.1, ShouldNotBeBetween, 2, 3)
So(1.1, ShouldBeBetweenOrEqual, .9, 1.1)
So(1.1, ShouldNotBeBetweenOrEqual, 1000, 2000)
So(1.0, ShouldAlmostEqual, 0.99999999, .0001)
帶容差比較,默認容差爲0.0000000001
So(1.0, ShouldNotAlmostEqual, 0.9, .0001)
(3)數據集合比較
So([]int{2, 4, 6}, ShouldContain, 4)
So([]int{2, 4, 6}, ShouldNotContain, 5)
So(4, ShouldBeIn, ...[]int{2, 4, 6})
So(4, ShouldNotBeIn, ...[]int{1, 3, 5})
So([]int{}, ShouldBeEmpty)
So([]int{1}, ShouldNotBeEmpty)
So(map[string]string{"a": "b"}, ShouldContainKey, "a")
So(map[string]string{"a": "b"}, ShouldNotContainKey, "b")
So(map[string]string{"a": "b"}, ShouldNotBeEmpty)
So(map[string]string{}, ShouldBeEmpty)
So(map[string]string{"a": "b"}, ShouldHaveLength, 1)
支持map、切片、通道、字符串
(4)字符串比較
So("asdf", ShouldStartWith, "as")
So("asdf", ShouldNotStartWith, "df")
So("asdf", ShouldEndWith, "df")
So("asdf", ShouldNotEndWith, "df")
So("asdf", ShouldContainSubstring, "sd")
So("asdf", ShouldNotContainSubstring, "er")
So("adsf", ShouldBeBlank)
So("asdf", ShouldNotBeBlank)
(5)異常比較
So(func(), ShouldPanic)
So(func(), ShouldNotPanic)
So(func(), ShouldPanicWith, "") // or errors.New("something")
So(func(), ShouldNotPanicWith, "") // or errors.New("something")
(6)類型檢查
So(1, ShouldHaveSameTypeAs, 0)
So(1, ShouldNotHaveSameTypeAs, "asdf")
(7)時間比較
So(time.Now(), ShouldHappenBefore, time.Now())
So(time.Now(), ShouldHappenOnOrBefore, time.Now())
So(time.Now(), ShouldHappenAfter, time.Now())
So(time.Now(), ShouldHappenOnOrAfter, time.Now())
So(time.Now(), ShouldHappenBetween, time.Now(), time.Now())
So(time.Now(), ShouldHappenOnOrBetween, time.Now(), time.Now())
So(time.Now(), ShouldNotHappenOnOrBetween, time.Now(), time.Now())
So(time.Now(), ShouldHappenWithin, duration, time.Now())
So(time.Now(), ShouldNotHappenWithin, duration, time.Now())數組
官方推薦使用導入GoConvey的輔助包以減小冗餘的代碼:. "github.com/smartystreets/goconvey/convey"
GoConvey包導入在工程代碼中以下:瀏覽器
import ( "testing" . "github.com/smartystreets/goconvey/convey" )
每一個單元測試的名稱需以 Test 開頭,並須要接收一個類型爲 *testing.T
的參數。
每一個測試用例須要使用Convey函數包裹起來,第一個參數爲string類型的測試用例描述;第二個參數通常爲 *testing.T
;第三個參數爲不接收任何參數也不返回任何值的函數(一般以閉包的形式書寫)。
Convey語句能夠無限嵌套,以體現各個測試用例之間的關係,只有最外層的 Convey 須要傳入*testing.T
類型變量,內層嵌套的Convey不須要傳入。閉包
func TestAdd(t *testing.T) { Convey("將兩數相加", t, func() { So(Add(1, 2), ShouldEqual, 3) }) }
GoConvey提供了Convey/So的Skip宏,用於想忽略某些斷言操做但不想刪除或註釋的場景。
SkipConvey:代表相應的閉包函數將不被執行。
SkipSo:代表相應的斷言將不被執行。
當存在SkipConvey或SkipSo時,測試日誌中會顯式打上"skipped"形式的標記:
當測試代碼中存在SkipConvey時,相應閉包函數中無論是否爲SkipSo,都將被忽略,測試日誌中對應的符號僅爲一個"⚠"
當測試代碼Convey語句中存在SkipSo時,測試日誌中每一個So對應一個"✔"或"✘",每一個SkipSo對應一個"⚠",按實際順序排列
無論存在SkipConvey仍是SkipSo時,測試日誌中都有字符串"{n} total assertions (one or more sections skipped)",其中{n}表示測試中實際已運行的斷言語句數。app
Operator.go文件:框架
package Operator import ( "errors" ) func Add(a, b int) int { return a + b } func Subtract(a, b int) int { return a - b } func Multiply(a, b int) int { return a * b } func Division(a, b int) (int, error) { if b == 0 { return 0, errors.New("Divisor is 0") } return a / b, nil }
Operator_test.go文件:ide
package Operator import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func TestAdd(t *testing.T) { Convey("將兩數相加", t, func() { So(Add(1, 2), ShouldEqual, 3) }) } func TestSubtract(t *testing.T) { Convey("將兩數相減", t, func() { So(Subtract(1, 2), ShouldEqual, -1) }) } func TestMultiply(t *testing.T) { Convey("將兩數相乘", t, func() { So(Multiply(3, 2), ShouldEqual, 6) }) } func TestDivision(t *testing.T) { Convey("將兩數相除", t, func() { Convey("除以非 0 數", func() { num, err := Division(10, 2) So(err, ShouldBeNil) So(num, ShouldEqual, 5) }) Convey("除以 0", func() { _, err := Division(10, 0) So(err, ShouldNotBeNil) }) }) }
So的函數原型以下:函數
func So(actual interface{}, assert assertion, expected ...interface{}) type assertion func(actual interface{}, expected ...interface{}) string
當assertion的返回值爲""時表示斷言成功,不然表示失敗,GoConvey框架中的相關代碼爲:單元測試
const ( success = "" needExactValues = "This assertion requires exactly %d comparison values (you provided %d)." needNonEmptyCollection = "This assertion requires at least 1 comparison value (you provided 0)." )
定製斷言函數以下:
func ShouldSummerBeComming(actual interface{}, expected ...interface{}) string { if actual == "summer" && expected[0] == "comming" { return "" } else { return "summer is not comming!" } }
單元測試以下:
func TestSummer(t *testing.T) { Convey("TestSummer", t, func() { So("summer", ShouldSummerBeComming, "comming") So("winter", ShouldSummerBeComming, "comming") }) }
根據ShouldSummerBeComming的實現,閉包中第一個So將斷言成功,第二個So將斷言失敗。
GoConvey兼容Go原生的單元測試,能夠直接使用Go命令來執行測試。
在測試代碼目錄下運行go test命令: go test -v
測試執行結果以下:
=== RUN TestAdd 將兩數相加 ✔ 1 total assertion --- PASS: TestAdd (0.00s) === RUN TestSubtract 將兩數相減 ✔ 2 total assertions --- PASS: TestSubtract (0.00s) === RUN TestMultiply 將兩數相乘 ✔ 3 total assertions --- PASS: TestMultiply (0.00s) === RUN TestDivision 將兩數相除 除以非 0 數 ✔✔ 除以 0 ✔ 6 total assertions --- PASS: TestDivision (0.00s) PASS ok GoExample/GoConvey 0.002s
查看goconvey用法goconvey -h
-cover:開啓覆蓋率統計功能
-depth int:掃描目錄的深度,-1:掃描無窮深度,0:掃描當前目錄
-excludedDirs string:將某些目錄排除在掃描外,多個目錄使用逗號分割
-host string:指定開啓HTTP服務的主機
-launchBrowser:觸發自動開啓瀏覽器,默認爲true
-port int:指定HTTP服務的端口
-workDir string:指定工做目錄,默認爲當前目錄
在測試用例源碼目錄下運行goconvey:goconvey -port 8081
在瀏覽器打開:
http://localhost:8081
結果以下: