Windows 環境為 CMake 加入 Gcov 以產生 Coverage Report

參考以下文章:

  1. 在 Windows 上使用 Google Test 來 Unittest 既有的 Legacy C 語言程式碼
  2. 使用 fff.h 來為 Google Test 製作各種 Test Double

完成 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 的工作流程:

gcov flow

編譯

重新 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 資料夾。

讓我們看一下會長成什麽樣子:

gcovr screenshot

綠色代表測試有執行到的地方,數字代表執行過的次數;紅色則相反,針對這些紅色部分,再去加強我們的測試程式吧!

References