在一個軟體開發的過程中,軟體測試是非常重要的一個環節。在衡量軟體測試的完整度時,代碼覆蓋率(Code Coverage)是一個被廣為使用的指標。在這篇Code Coverage教學文章中,將會介紹Code Coverage的定義以及產生Code Coverage Report的工具。希望能夠讓進行軟體測試的人能夠更輕易地了解如何系統化的完成一項可靠的測試任務。
什麼是代碼覆蓋率(Code Coverage)?
在軟體開發的專案中,由於程式中可能很多屬於例外處理的部分或是一些功能沒有被使用到而導致我們在進行軟體測試的時候只跑了「大部份狀況」的程式碼,這使得我們的測試程式只使用到所有程式中的一部分程式碼。假設我們總共寫了1000行程式碼,而在測試程式中只跑了其中500行程式碼,這樣我們就稱這個測試的代碼覆蓋率為50%。
代碼覆蓋率的類別
在討論覆蓋率時,通常會針對「語句覆蓋率」、「分支覆蓋率」、以及「函式覆蓋率」做進一步的分析。
語句覆蓋率 (Statement Coverage)
語句覆蓋率就是針對程式中的Statement進行統計,計算總共有多少行指令在程式中被運行到。變數的宣告或是標頭檔(Header File)的引用皆不會被計算在這中間。舉例來說,假設我們寫了一個程式含有1000行程式碼,而其中200行是在做變數宣告,則這200行程式碼將不會被列入統計範圍,也就是由剩餘的800行程式中去計算有多少行程式被測試程式運行到。Statement Coverage也是最被廣泛使用的覆蓋率計算方式。
分支覆蓋率 (Branch Coverage)
一個程式通常會有很多的分支(Branch),例如一個if/else的條件是就會產生一個分支。在進行分支覆蓋率計算時就是統計程式共有多少分支,以及在測試程式中有多少分支被執行到。這也是一個被廣泛使用覆蓋率計算方式。
函式覆蓋率 (Function Coverage)
一個大型軟體專案會包含很多函式(Function),而函式覆蓋率就是字面上的意思。假設我的程式有100個Functions,在測試程式運行過程有50個Functions被運行到,此測試的函式覆蓋率就是50%。由於函式覆蓋率所提供的測試資訊不夠詳細,太過粗略,一般在實務上比較少使用。
如何產生代碼覆蓋率資訊?
目前有很多收集產生Code Coverage資訊的工具。在這篇文章中我想介紹一個我自己在C++軟體開發過程中經常使用的工具gcovr。這是一個可以管理使用GNU gcov以及產生Code Coverage報告的工具。整個使用的流程就是以下三個步驟:
- 編譯含有代碼覆蓋率資訊的程式
- 執行編譯後的程式
- 使用gcovr產生Code Coverage報告
編譯含有代碼覆蓋率資訊的程式
在使用GNU gcc或是clang編譯程式時,加入–coverage或是-fprofile-arcs -ftest-coverage等Compiler Flags開啟Code Coverage功能來編譯要分析的程式,編譯器在編譯程式時就會安插可用於分析代碼覆蓋率的資訊在執行檔中。例如使用以下指令進行編譯。
$ g++ -fprofile-arcs -ftest-coverage foo.cpp -o foo
執行編譯後的程式
在上面的例子中會產生一個可執行檔foo,執行編譯出來的程式。
$ ./foo
這個程式會照原本設計的一樣運行。通常在進行軟體測試時,這個程式會包含各個Unit Test的測試項目在其中。
使用gcovr產生Code Coverage報告
以下為gcovr的使用教學,詳細的說明文件可以參考其網站。
安裝gcovr
gcovr可使用pip安裝其Python package。可使用以下指令安裝最新的Stable Release。
$ pip install gcovr
也可以使用以下指令安裝最新的Development版本
$ pip install git+https://github.com/gcovr/gcovr.git
設定Filter
當專案過大時,我們通常會設定Filter來選擇要觀察的程式碼檔案。因此會寫一個cfg檔案來描述哪些檔案是我要觀察的。例如在以下的filter檔中就描述了我想要觀察所有在example/src/目錄中的程式檔案。這一個步驟也可以選擇不做。
filter = example/src/*
json = yes
執行gcovr
使用以下指令將所設定的filter檔案轉換成json檔案。
$ gcovr --config filter.cfg > filter.json
在使用以下指令產生HTML格式的Code Coverage報告。
$ gcovr --add-tracefile filter.json --html-details coverage.html
如此一來即可產生像以下一樣的Code Coverage結果。在這份報告中包含了Statement Coverage以及Branch Coverage。而由於我們有使用–html-details參數,每一個檔案都可以使用此HTML頁面點擊進去看到哪幾行程式碼被執行到以及哪幾行沒有被執行到。這是一個相當好用的工具。

總結
這篇文章中介紹了代碼覆蓋率以及可以產生代碼覆蓋率分析報告的工具。一個專案的代碼覆蓋率越高表示軟體測試的越完善。一般而言都是伴隨著Unit Test一起分析,來了解基本單元測試共覆蓋了多少程式碼。原則上會希望整個專案的覆蓋率可達75%以上,而盡量希望每個各別程式檔案也都能有75%以上。而如果能達到90%以上,就會是非常優秀的測試了。希望大家都能有一個完整且系統化的流程來進行軟體測試,順利開發出具有一定品質的軟體。