在嵌入式平台上使用了gtest白盒測試工具,覆蓋了被測函數,但是不知道自己測試的效果如何,測試行覆蓋率、函數覆蓋率,分支覆蓋率的數據。
便開始研究gcov這個代碼覆蓋率工具能否使用,來檢查白盒測試的效果,以及指引測試改進的方向。經過多次嘗試和研究,
在嵌入式平台上可以使用gcov這個工具,不過操作稍微復雜點。
環境要求:
1、有被測組件的源代碼
2、對應平台的交叉編譯器必須包含gcov功能
3、安裝好lcov工具
4、相應的嵌入式設備
使用gcov/lcov測試代碼覆蓋率,總共分為四步:
1、在組件編譯中添加gcov編譯參數,然后編譯debug版本,同時生成gcno文件
2、在gtest編譯中使用添加編譯參數的組件
3、執行生成的程序,生成代碼覆蓋文件gcda
4、使用lcov工具解析gcno和gcda文件,生成html報表文件
下面詳細說明四個步驟如何操作:
1、在組件編譯中添加編譯參數
我們測試的是組件,文件形式是靜態庫(.a)或者動態庫(.so)。為了統計測試的代碼覆蓋率,我們需要在編譯的時候添加如下參數。
需要添加的編譯參數為:-fprofile-arcs -ftest-coverage;同時添加參數對應的庫lgcov
添加完成后,進行編譯。然后查找,找到生成的后綴名為gcno文件的話,則說明成功。
重要:gcno文件生成的路徑,這個一般是根據Makefile腳本指定的不同路徑來確定的,有的時候與源代碼在一起,有的時候與中間文件在一起。
但是不管gcno的路徑在哪里,要記住這個路徑。后續有用的。
2、在gtest編譯中使用帶gcov的組件
A、修改編譯腳本,添加-lgcov 編譯參數
B、把使用的庫文件替換為添加gcov編譯參數的組件
(如何在嵌入式平台中使用gtest,請參考 http://www.cnblogs.com/StitchSun/p/4430362.html)
3、執行gtest測試程序
把編譯好的測試程序在對應的設備上執行測試,執行沒有錯誤后,然后查看嵌入式設備的目錄,到與生成gcno路徑一致的目錄下,查找gcda文件
gcda文件生成路徑為編譯時生成gcno的路徑,不過gcno是在編譯服務器上,gcda是在程序運行的嵌入式設備上。
4、使用lcov解析gcda和gcno文件
把設備的gcda文件下載到編譯服務器,同時把編譯時生成的gcno文件也復制到同一個目錄。
對於前面名稱相同的文件,gcda和gcno文件必須在同一目錄下。
要使用lcov工具,可以在http://ltp.sourceforge.net/coverage/lcov.php 下載最新的版本。
但是這個工具無法直接解析嵌入式平台產生的gcno和gcda格式的文件,需要修改一個地方。
即這個工具默認的是使用linux系統自帶的gcov,需要修改為使用交叉編譯器的gcov工具。
修改的文件為:bin/geninfo 的,把原來的gcov修改為交叉編譯的gcov。
修改完成,保存退出。
以使用的isi3518 交叉編譯器為例,執行下面的命令:
a /opt/lcov_test/hisi3518/lcov-1.9/bin/lcov -d . -t 'test' -o 'test.info' -b . -c
b /opt/lcov_test/hisi3518/lcov-1.9/bin/genhtml -o result test.info
看到上面的提示,說明執行成功了。把result文件夾下載到windows上,打開里面的index,就可以看到結果了。
常見問題:
1、geninfo: ERROR: …: reached unexpected end of file
注意,lcov 最好使用 1.9 及以上版本,否則可能遇到如下錯誤:
geninfo: ERROR: …: reached unexpected end of file
2、 gcov解決stamp mismatch with graph file
使用 hexdump -e '"%x\n"' -s8 -n4 命令分別解析 XXX.gcno和XXX.gcda文件
如果生成的碼不一致,則說明gcno和gcda不是一次編譯生成的,需要重新編譯。
命令使用如下:
hexdump -e '"%x\n"' -s8 -n4 dns_shell.gcno
3、找不到源代碼
在解析gcno和gcda時,要和源代碼在一個服務器上,並且源代碼的路徑在生成gcno和gcda后
沒有變動過。不然會提示找不到源代碼。
參考:
在研究中,下面的鏈接有很大的幫助。表示感謝。
http://blog.sina.com.cn/s/blog_7e4ac8b501018b27.html
這個參考中的第三步 gcov產生報告信息: test.c.gcov 不用執行