單元測試的主要目的是獲取應用程序中可測試軟件的最小片段,將其同代碼的其余部分隔離開來,然后確定它的行為是否與預期的一樣。單元測試并不能保證程序是完美無缺的,但是在所有的測試中,單元測試是第一個環節,也是最重要的一個環節。單元測試的對象是軟件設計中的最小單位--模塊,它是一種程序員對自己的代碼進行自測試的工作,其測試依據就是軟件模塊的詳細設計文檔。單元測試通常采用白盒測試的方式,白盒測試也稱結構測試或邏輯驅動測試,已知產品內部工作過程,通過測試來檢測內部動作是否正常。測試按照程序內部結構進行,檢驗程序中的每條通路是否正確工作,而不顧它的功能。測試是從代碼的路徑結構和內部邏輯信息設計測試用例并覆蓋全部代碼、分支、路徑、條件。 所以,單元測試的一個很重要的指標就是代碼覆蓋率,很多軟件開發標準化組織都對單元測試的代碼覆蓋率有很明確的要求,低于標準就意味著單元測試不通過。
目前有很多單元測試工具都支持程序覆蓋率的自動統計,應用較廣的分析覆蓋率的工具有 Logiscope TestChecker、 TrueCoverage 、 PureCoverage 等,本文主要是介紹如何使用Rational公司的PureCoverage工具統計測試代碼覆蓋率。PureCoverage是Rational公司的單元測試工具PurifyPlus三套件之一,PurifyPlus的另外兩個套件分別是內存檢查工具purify和代碼效率分析工具pureQuantity。本文主要介紹如何使用PureCoverage配合Microsoft的開發工具Visual C++統計單元測試的代碼覆蓋率。PureCoverage通過記錄執行過的代碼,生成代碼覆蓋分析報告,其代碼覆蓋分析可以詳細到語句級,技術上的原理就是使用目標碼插入OCI(Object Code Insertion)技術。所謂的目標對象插入技術,就是直接對目標碼進行分析,并插入相應的匯編代碼,不過源代碼插入SCI(Source Code Instrumentation)和執行碼替換ECI(Executable Code Interception)都需要源代碼或編譯環境的支持,并且會引起程序運行緩慢和系統資源占用過多的問題。但是瑕不掩瑜,PureCoverage憑借著與Visual Studio集成開發環境的無縫連接,依然是單元測試工具的首選利器。
PureCoverage有兩種運行界面,一種是應用程序界面,可以脫離開發環境獨立運行;另一種是嵌入式界面,可以集成到Visual Studio的集成開發環境中,不過兩種運行方式的基本功能是相同的。下面用一個簡單的例子作個演示,使大家對PureCoverage有一個感性的認識,這個例子就是PureCoverage自帶的一個例子hello.exe。
首先運行PureCoverage,然后選擇“File”菜單的“Run”命令,在彈出的“Run Program”對話框中選擇hello.exe程序:
圖1. 選擇程序
由于hello.exe是使用Visual C++ 6.0編寫的Win32應用程序,所以在“Collect Data From”選項處選擇“Unmanaged Code(非托管代碼)”,點擊“Run”按鈕就開始運行Hello.exe。PureCoverage首先分析Hello.exe裝載的模塊,然后潤行hello.exe,出現一個標題是“Hello,World”的消息框,這是hello.exe程序的提示,要用戶選擇是不是看看當前的時間,我們先點擊“確定”按鈕看看結果。hello.exe彈出另一個消息框顯示當前時間,點擊“確定”按鈕結束程序的運行,此時PureCoverage已經統計出了結果,如圖(2)所示:[Page]
圖2. 運行結果的“Module View”視圖
這個視圖顯示了hello.c的有兩個函數,DisplayLocalTime()和WinMain(),在剛才那次測試運行中被調用的次數和代碼行覆蓋率。用鼠標雙擊函數名可以將視圖切換到代碼窗口,如圖(3)所示:
圖3. 運行結果的“Source Code”視圖
代碼視圖中被標記為藍色的代碼是剛才這次測試走過的代碼,被標記為紅色的代碼表示這次測試沒有走過的代碼。如果想了解每個函數的具體情況,可以點擊工具欄的“Function List”圖標,圖(4)就是本例中的函數列表,包括函數被調用的次數,總的代碼行數,被測試過的行數以及代碼覆蓋率。
圖4. Function List 顯示
有時候一次測試通常不能覆蓋所有的代碼,以上面的hello.exe為例,WinMain()函數的一個分支就沒有走到,PureCoverage充分考慮到了這種情況,它能夠記錄每一次測試結果,并提供了對結果進行分析、對比和合并的功能。下面我們再Run一下hello.exe,這次選擇不看當前時間,使程序走過WinMain()函數的另一個流程。此時PureCoverage右邊的“Navigator”窗口就記錄下了對hello.exe的兩次測試結果,如圖(5)所示:
圖5. 查看Navigator窗口
在Navigator窗口上用鼠標雙擊第二次測試的結果條目,就可以在右邊看到這次測試的詳細信息,如圖(6)所示,這次測試Missing了DisplayLocalTime()函數,只走過了WinMain()函數的else分支。