被測服務是go服務,測試腳本是python等非go語言實現,可參考以下兩種方法實現go服務的測試覆蓋率統計。
方法一:go test 方式,不編譯二進制文件
- 創建main_test.go文件
或者與你的 func main(){}方法所在的文件名同名的test文件。比如,有如下main.go文件:
package main
import (
"github.com/labstack/echo"
"hello-go/api"
)
func main() {
e := echo.New()
e.GET("/", api.HelloWorld)
e.GET("/api1", api.Api1)
e.GET("/api2", api.Api2)
e.Logger.Fatal(e.Start(":8001"))
}
根據以上main.go文件,創建以下main_test.go文件
package main
import (
"fmt"
"net/http"
"os"
"os/signal"
"testing"
)
var exitChan chan int
func testHandler(w http.ResponseWriter, req *http.Request) {
exitChan <- 666 }
func startServer() {
go main() // main.gomain
}
func TestExternal(t *testing.T) {
// start server need be tested in separate go thread
go startServer()
// go test starts a dummy http server, which is used to
// end the current go test gracefully when it's accessed.
http.HandleFunc("/", testHandler)
go http.ListenAndServe(":9999", nil)
// go test9999
// 9999
exitChan = make(chan int)
sigChann := make(chan os.Signal)
signal.Notify(sigChann, os.Interrupt)
select {
case sig := <-sigChann:
fmt.Printf("exit as received signal: %v\n", sig)
case val := <-exitChan:
fmt.Printf("exit as received http request: %v\n", val)
}
}
- 執行go test啟動服務
進入main_test.go所在目錄,一般在代碼根目錄,執行go test命令:
go test -coverprofile=cov.out -coverpkg ./... &
# -coverprofile 產出的覆蓋率文件
# -coverpkg 要統計的覆蓋率文件源碼,可以指定文件
# & 后台執行
- 執行測試用例
curl 127.0.0.1:8001 #服務是否正常啟動
curl 127.0.0.1:8001/api1 #測試用例1
curl 127.0.0.1:8001/api2 #測試用例2
curl 127.0.0.1:9999 #服務停止,注意:只有停止了服務才能生成覆蓋率文件
- 生成覆蓋率報告
在代碼根目錄會生成cov.out覆蓋率文件。為了方便查看和瀏覽,可將out文件轉換為html報告進行查看,執行命令如下:
go tool cover -html cov.out -o index.html
- 拷貝index.html到本地可查看代碼行覆蓋情況
方法二:編譯出二進制文件執行
- 生成覆蓋率二進制文件的原理介紹(插樁產物)
要運行系統測試,需要應用程序的編譯二進制文件。然后,在具有不同配置的不同環境中執行此二進制文件。Golang提供了一種獨特的方法來生成 覆蓋率二進制文件,而不是go build生成的默認二進制文件。
生成的代碼覆蓋率二進制文件在每一行代碼后寫入一個唯一的計數器,並檢查在執行二進制文件后調用此計數器的次數。
更多的技術細節可以在go-cover文檔中找到。go cover 官方文檔:https://blog.golang.org/cover
當執行go test時,覆蓋率二進制文件會自動生成並在之后處理。Golang允許使用以下命令生成此覆蓋率二進制文件:
go test -c -covermode=count -coverpkg ./...
#
# -c 表示 生成測試二進制文件
# -covermode=count 表示 生成的二進制中包含覆蓋率計數信息
# -o packagename.test 表示 覆蓋率二進制文件名
# -coverpkg ./... 表示 要統計的覆蓋率文件源碼
更多的參數信息可以執行go test -help來查看。
- 創建main_test文件
現在我們知道了如何生成二進制文件,我們必須確保二進制文件將按預期執行。您的代碼需要滿足以下要求,才能按照預期生成二進制。
package中至少有一個*_test.go文件,否則不會生成二進制文件。建議創建main_test.go 文件,或者與你的func main(){}所在的文件名同 名的test文件,與上一個方法類似,需要創建一個main_test.go文件讓go test來插樁
main_test.go 同上
該文件定義了一個systemTest標志,並包含一個調用main函數的測試用例。
運行測試二進制文件開始執行測試。在例子中,這意味着調用TestExternal,因為這是唯一的測試。運行TestExternal 意味着調用main(),它 將像普通二進制文件那樣啟動應用程序。這也就意味着運行測試產生的二進制文件與運行普通二進制文件相同,只是運行測試產生的二進制文件將 會跟蹤覆蓋率執行,也就是我們常說的打樁。
為了防止在運行單元測試時運行此測試,添加了命令行標志systemTest。如果未設置,則不會調用main()函數。而要運行系統測試,必須在執行測 試二進制文件期間通過附加-systemTest來設置標志。
- 生成插樁后的覆蓋率二進制文件
在代碼根目錄執行以下命令:
go test -c -covermode=count -coverpkg ./... -o hello.test
執行完成后將生成一個 hello.test文件
- 以打樁二進制文件啟動服務
//啟動服務(打樁二進制)
./hello.test -systemTest -test.coverprofile cov.out &
-
執行測試case
-
生成覆蓋率報告
執行完用例並停止服務后,在代碼根目錄下生成覆蓋率文件cov.out
為了方便查看和瀏覽,可將out文件轉換為html報告進行查看,執行命令如下:
go tool cover -html cov.out -o index.html
參考文檔
https://www.elastic.co/cn/blog/code-coverage-for-your-golang-system-tests