單元測試是代碼質量的重要保證,測試覆蓋率是關鍵的衡量指標。
在golang 中,通過go test 進行單元測試,並可以分析覆蓋率。
單元測試覆蓋率
示例代碼
首先看下示例代碼。
新建目錄utils,目錄有以下文件
ll
total 16
-rw-r--r-- 1 lanyang staff 132B 12 31 21:09 add_hint.go
-rw-r--r-- 1 lanyang staff 360B 12 31 21:09 add_hint_test.go
add_hint.go 文件內容如下:
package utils
func AddPrefix(s string) string {
return "good " + s
}
func AddSuffix(s string) string {
return s + "!"
}
add_hint_test.go 文件內容如下:
package utils
import (
"testing"
"strings"
)
func TestAddPrefix(t *testing.T) {
src := "boy"
dst := AddPrefix(src)
if !strings.HasPrefix(dst, "good") {
t.Fatalf("unexpected dst:%s", dst)
}
}
func TestAddSufffix(t *testing.T) {
src := "good"
dst := AddSuffix(src)
if !strings.HasSuffix(dst, "!") {
t.Fatalf("unexpected dst:%s", dst)
}
}
以上代碼分別在字符串頭部和尾部分別添加字符串前綴和后綴。
執行單元測試
go test -v -covermode=set -coverprofile=hint_test.out ./
=== RUN TestAddPrefix
--- PASS: TestAddPrefix (0.00s)
=== RUN TestAddSufffix
--- PASS: TestAddSufffix (0.00s)
PASS
coverage: 100.0% of statements
ok _/go_exercise/utils 0.007s coverage: 100.0% of statements
從終端輸出,可以看到整體的測試情況。
其中,
-covermode
有三種模式:
- set 語句是否執行,默認模式
- count 每個語句執行次數
- atomic 類似於count,表示並發程序中的精確技術
-coverprofile
是統計信息保存的文件。
這里指定的輸出文件是hint_test.out,其內容如下:
mode: set
/go_exercise/utils/add_hint.go:4.33,7.2 1 1
/go_exercise/utils/add_hint.go:11.33,14.2 1 1
生成coverprofile后,當前目錄下文件列表如下:
ll
total 24
-rw-r--r-- 1 lanyang staff 132B 12 31 21:09 add_hint.go
-rw-r--r-- 1 lanyang staff 457B 1 2 20:37 add_hint_test.go
-rw-r--r-- 1 lanyang staff 164B 1 2 20:38 hint_test.out
查看具體的測試覆蓋情況
上面終端輸出中,可以看到整體的覆蓋率。但沒有每個更具體的覆蓋情況。
下面通過使用剛才生成的profile文件具體看下覆蓋情況。
(1)查看每個函數的覆蓋情況:
go tool cover -func=hint_test.out
/go_exercise/utils/add_hint.go:4: AddPrefix 100.0%
/go_exercise/utils/add_hint.go:11: AddSuffix 100.0%
total: (statements) 100.0%
(2)使用網頁方式展示覆蓋率情況
go tool cover -html=hint_test.out
執行命令后,跳出瀏覽器頁面以圖形化的方式展示測試覆蓋情況。
從圖中可以看到,根據顏色就可以分辨出哪些代碼已覆蓋,哪些代碼沒覆蓋。
如果需要測試當前目錄下所有package 的單元測試覆蓋情況,可執行
go test -v -covermod=set -coverprofile=all_pkg.out ./...
./...
表示當前目錄及其子目錄下的所有package。