參考以下文章:
完成 Unittest 之後,還有一件很重要的事:產生 Coverage 報表,好讓我們知道總共測試了哪幾行 Code。按照文章 1 的步驟做完之後,你的電腦中應該就有 gcov 這套工具,可以透過指令檢查:
$ gcov --version
編輯 CMakeLists.txt 以記錄 Code 執行數據
回到我們根目錄的 CMakeLists.txt 檔案,加入以下設定:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
若你的測試目標是 32bit 的系統,可加入 -m32 參數。
懶人寫法可以寫一個 -fprofile-generate,就包含 -fprofile-arcs、-ftest-coverage 這兩個參數。
用 Gcov 產生 Coverage Report
Gcov 的工作流程:
編譯
重新 CMake 編譯之後,發現多出副檔名為 gcno 的檔案,這是參數 -ftest-coverage
的作用,gcno 檔案包含反組譯資訊,能夠推算出原始程式碼的檔案位置及行數。
執行
再重新執行一次 ctest,這次發現新產生出副檔名為 gcda 的檔案,這是參數 -fprofile-arcs
的作用,gcda 檔案記錄著程式碼執行過程的資訊。
產生涵蓋率報表
$ gcov path/to/a.gcda
看一下輸出檔案。
-: 20:#include "main/task.h"
-: 21:#include <shr_lib/debug.h>
-: 22:
4: 23:U8 disp_lookup_tbl(U32 job_op)
-: 24:{
4: 25: U8 task_id = TID_INVALID;
-: 26:
4: 27: switch (job_op)
-: 28: {
4: 29: case OP_START_TIMER:
4: 30: task_id = TID_DISP;
4: 31: break;
#####: 32: default:
#####: 33: task_id = TID_INVALID;
#####: 34: break;
-: 35: }
-: 36:
4: 37: return task_id;
-: 38:}
撒花~雖然是很簡單的純文字輸出,但我們成功得到一份涵蓋率報表了!
匯整所有報表
但我們不可能一份一份檔案去呼叫 gcov 指令,而且輸出文字檔也稍微難以閲讀,好在網路上有許多工具,既幫我們收集 gcov 執行結果,也幫我們轉換成好看的格式。例如 lcov,但這是一個 Linux Tool,意味著 Windows 上不能用!查了半天發現一套純 Python 的解決方法:Gcovr。
安裝:
$ pip install gcovr
即可使用:
$ mkdir gcovr
$ gcovr --html --html-details -o gcov/index.html
進階參數説明:
--exclude
排除檔案或資料夾,可以多次指定--html
輸出為網頁格式,可用瀏覽器瀏覽--html-details
產生每一個 C 檔的 HTML 格式 Coverage Report-o
輸出檔案,如果用 html 格式可以指定如-o gcov/index.html
將檔案搜集到新建的gcov
資料夾。
讓我們看一下會長成什麽樣子:
綠色代表測試有執行到的地方,數字代表執行過的次數;紅色則相反,針對這些紅色部分,再去加強我們的測試程式吧!