Golang筆記-單元測試test初探

爲何須要單元測試

其實在很長一段時間,包括如今,我都很不喜歡寫單元測試。由於維護單元測試的成本很高。只有接口作了一點變動,那麼單元測試就必須作相同的變動,不然會致使測試不經過。html

那麼反過來,只要每次在提交代碼都去運行一次單元測試。這樣能夠很快的檢查到你對代碼更改是否影響了正常的業務邏輯,固然很大一部分是多是別人寫的那部分代碼。由於你不肯定本次的修改是否會影響到別人的那部分。因此單元測試仍是頗有必要的。git

單元測試最基本的應用

go語言中單元測試是開箱即用的,官方提供了test包。不用像PHP中須要單獨配置unitgithub

go test 最基本使用

go test 命令是golang單元測試的最基本使用golang

go test -v

go test -v是咱們比較經常使用的一個測試命令,用於執行測試,並打印額外的輸出。

新建一個項目用於示例微信

test
│  main.go
│  main_test.go

能夠看到我在main.go的同級目錄建立了一個main_test.gogo語言中,單元測試的代碼必須跟須要測試的代碼在同一個包裏面。且命名必須遵循上面的那種結構規範,即:文件名_test.goapp

我在main.go中建立兩個函數來分別獲得字符串相加的結果。函數

func JoinStrUseSprint(a,b string) string {
    return  fmt.Sprintf("%s%s",a,b)
}

func JoinStrUseNor(a,b string) string {
    return  a+b
}

main_test.go中的測試代碼工具

import "testing"

func TestJoinStrUseNor(t *testing.T) {
    c := JoinStrUseNor("aaa","bbb")
    t.Log(c)
}

func TestJoinStrUseSprint(t *testing.T) {
    c := JoinStrUseSprint("aaa","bbb")
    t.Log(c)
}

測試代碼中使用了 testing包。並且每一個測試函數必須是以Test開頭,有且只有一個參數t *testing.T.t.Log()函數爲輸出一段Log日誌 這樣一個簡單的單元測試就完成了。單元測試

這個時候咱們運行go test,結果以下。學習

test>go test
PASS
ok      test    0.360s

能夠看到測試經過了。可是發現並無咱們指望的日誌輸出。若是咱們要獲得輸出的結果,咱們須要一個額外的參數,具體命令以下:

test>go test -v
=== RUN   TestJoinStrUseNor
--- PASS: TestJoinStrUseNor (0.00s)
    main_test.go:7: aaabbb
=== RUN   TestJoinStrUseSprint
--- PASS: TestJoinStrUseSprint (0.00s)
    main_test.go:12: aaabbb
PASS
ok      test    0.480s

這個時候就能夠看到很詳細的測試流程與輸出的測試的log

go test -cover
不少時間咱們須要看單元測試的覆蓋率,這個時候咱們就須要 go test -cover了。

咱們一樣使用上面的代碼。

test>go test -cover
PASS
coverage: 100.0% of statements
ok      test    0.440s

能夠看到單元代碼覆蓋率是100%。這個是咱們在main文件裏面在增長一個函數。

func JoinStrUseSprint(a,b string) string {
    return  fmt.Sprintf("%s%s",a,b)
}

func JoinStrUseNor(a,b string) string {
    return  a+b
}
func Run()  {
    fmt.Println("I'm run,and I'm happy!")
}

而後再執行cover,獲得了覆蓋率爲66.7

test>go test -cover
PASS
coverage: 66.7% of statements
ok      test    0.398s

固然-v -cover是能夠同事使用的。

test>go test -cover -v
=== RUN   TestJoinStrUseNor
--- PASS: TestJoinStrUseNor (0.00s)
    main_test.go:7: aaabbb
=== RUN   TestJoinStrUseSprint
--- PASS: TestJoinStrUseSprint (0.00s)
    main_test.go:12: aaabbb
PASS
coverage: 66.7% of statements
ok      test    0.429s

不少時候咱們須要將單元測試覆蓋率寫到一個文件中,這時候咱們再-cover中增長一些額外的參數

>go test -coverprofile test.cover
>go tool cover -html=test.cover -o coverage.html
  • 第一個命令:-coverprofile filename將覆蓋率的profile寫入指定文件中。
  • 第二個命令:go tool cover -html=test.cover -o coverage.html將覆蓋率的文件寫入可視化的html文件中

打開converage.html
以下圖:
cover_01.png

其實這裏能夠借用一個很好的第三方包。

go get github.com/smartystreets/goconvey

安裝完成,直接再項目目錄下執行

test>goconvey
2020/05/16 21:46:43 goconvey.go:61: Initial configuration: [host: 127.0.0.1] [port: 8080] [poll: 250ms] [cover: true]
2020/05/16 21:46:43 tester.go:19: Now configured to test 10 packages concurrently.
2020/05/16 21:46:43 goconvey.go:178: Serving HTTP at: http://127.0.0.1:8080
2020/05/16 21:46:43 integration.go:122: File system state modified, publishing current folders... 0 3179270049
2020/05/16 21:46:43 goconvey.go:118: Received request from watcher to execute tests...
2020/05/16 21:46:43 goconvey.go:105: Launching browser on 127.0.0.1:8080
2020/05/16 21:46:43 goconvey.go:111: exec: "start": executable file not found in %PATH%
2020/05/16 21:46:43 goconvey.go:113:
2020/05/16 21:46:44 executor.go:69: Executor status: 'executing'
2020/05/16 21:46:44 coordinator.go:46: Executing concurrent tests: test
2020/05/16 21:46:45 parser.go:24: [passed]: test

按照提示打開http://127.0.0.1:8080/就會獲得一個很炫酷的覆蓋率界面
cover_02.png

Golang單元測試的基礎今天就暫時到這裏面,下面幾個testing包的經常使用斷言方法.

// 輸出測試日誌
t.Logf()
t.Logf()
// 標記錯誤,但仍然執行後面的語句
t.Fail()
// 獲取是否當前用例是執行錯誤的
t.Failed()
// 錯誤輸出,等於 t.Logf 再執行 t.Fail()
t.Errorf("%s", "run ErrorF")
// 標記函數錯誤,並中斷後面的執行
t.FailNow()
// 致命錯誤輸出,等同於調用了 t.Logf 而後調用 t.FailNow()
t.Fatalf("%s", "run Fatelf")

下一篇咱們會寫到 golang中的一些基準測試,以及一些測試的工具。

更多學習內容,同步更新到公衆號,期待與您一塊兒交流
白色底可愛幼稚微信公衆號底部二維碼.png

相關文章
相關標籤/搜索