工程效能領域,測試覆蓋率度量老是繞不開的話題,咱們也不例外。在七牛雲,咱們主要使用go語言構建雲服務,在考慮系統測試覆蓋率時,最先也是經過圍繞原生go test -c -cover
的能力來構建。且咱們已經作了不少自動化工做,可以針對不少類型的代碼庫,自動插樁服務,自動生成TestMain()等方法,但隨着接入項目愈來愈多,以及後面使用場景的不斷複雜化,咱們發現這套方案仍是有其先天侷限,會讓後面愈來愈難受:git
-
程序必須關閉才能收集覆蓋率。若是將這套系統僅定位在收集覆蓋率數據上,這個痛點倒也能忍受。可是若是想進一步作精準測試等方向,就很受侷限。github
-
由於不想污染被測代碼庫,咱們採起了自動化的方式,在編譯階段給每一個服務生成相似main_test.go文件。但這種方式,其最難受的地方在於flag的處理,要知道go test命令自己會調用flag.Parse方法,因此這裏須要自動化的修改源碼,保證被測程序的flag定義,要先於go test調用flag.Parse以前。可是,隨着程序本身使用flag姿式的複雜化,咱們發現愈來愈難有通用方案來處理這些flag,有點難受。架構
-
受限於
go test-c
命令的先天缺陷,它會給被測程序注入一些測試專屬的flag,好比-test.coverprofile, -test.timeout等等。這個是最難受的,由於它會破壞被測程序的啓動姿式。咱們知道系統測試面對是完整被測集羣,若是你須要專門維護一套測試集羣來作覆蓋率收集時,就會顯得很是浪費。好鋼就應該用在刀刃上,在七牛雲,咱們倡導極客文化,追求用工程師思惟解決重複問題,而做爲業務效率部門,咱們本身更應該走在前列。工具
也是由於以上的種種考量,咱們內部一直在優化這一套系統,到今天這一版,咱們已從架構和實現原理上完成了顛覆,可以作到無損插樁,運行時分析覆蓋率,當屬很是優雅。性能
Goc - A Comprehensive Coverage Testing System for The Go Programming Language
一圖勝千言:測試
使用 goc run.
的姿式直接運行被測程序,就能在運行時,經過 goc profile
命令方便的獲得覆蓋率結果。是否是很神奇?是否是很優雅?優化
這個系統就是goc, 設計上但願徹底兼容go命令行工具核心命令(go build/install/run)。使用體驗上,也但願向go命令行工具靠攏。如下是goc 1.0版本支持的功能:ui
系統測試覆蓋率收集方案
有了goc,咱們再來看如何收集go語言系統測試覆蓋率。總體比較簡單,大致只須要三步:spa
-
首先經過
goc server
命令部署一個服務註冊中心,它將會做爲樞紐服務跟全部的被測服務通訊。命令行 -
使用
goc build--center="<server>"
命令編譯被測程序。goc不會破壞被測程序的啓動方式,因此你能夠直接將編譯出的二進制發佈到集成測試環境。 -
環境部署好以後,就能夠作執行任意的系統測試。而在測試期間,能夠在任什麼時候間,經過
goc profile--center="<server>"
拿到當前被測集羣的覆蓋率結果。
是否是很優雅?
goc 核心原理及將來
goc在設計上,拋棄老的 go test-c-cover
模式,而是直接與 go tool cover
工具交互,避免因 go test
命令引入的一系列弊端。goc一樣沒有選擇本身作插樁,也是考慮go語言的兼容性,以及性能問題,畢竟 go tool cover
工具,原生採用結構體來定義counter收集器,每一個文件都有單獨的結構體,性能相對比較可靠。goc旨在作go語言領域綜合性的覆蓋率工具以及精準測試系統,其還有很長的路要走:
-
基於PR的單測/集測/系統覆蓋率增量分析
-
精準測試方向,有必定的產品化設計體驗,方便研發與測試平常使用
-
擁抱各類CICD系統
當前goc已經開源了(https://github.com/qiniu/goc),歡迎感興趣的同窗,前往代碼倉庫查看詳情並Star支持。固然,咱們更歡迎有志之士,可以參與貢獻,和咱們一塊兒構建這個有意思的系統。