唐躍川,趙渝潔,饒義瓊
(重慶金美通信有限責任公司,重慶 400030)
隨著軟件業的日益壯大和逐步成熟,軟件測試也在不斷發展。從簡單的開發人員自行調試逐漸往規范化、流程化的方向發展。其活動過程十分復雜,如果不借助輔助工具,僅靠人工處理,則不僅效率低下、工作量巨大,而且可能出現無法解決的問題。而單元測試又對測試人員的從業素質提出了更高要求。鑒于以上問題,利用一套好的單元測試工具來幫助軟件測試人員提高工作效率,提高工作質量,改善工作條件是非常有必要的。
C++Test是美國Parasoft 公司研發的一款針對CC++的單元測試工具,具有自己的專利技術,其功能覆蓋了從代碼靜態檢查到仿真代碼運行環境進行動態檢查,以及自動生成測試用例和回歸測試等方方面面,從橫向的測試寬度和縱向的測試過程都能夠給軟件單元測試提供足夠的支持。
C++Test 提供了以下一些功能:
(1)靜態代碼檢測。C++ TEST 內建了包括MISRA C++2008 在內的共1456種編程規范,用戶可根據實際需要選擇符合自己要求的規范來對代碼進行靜態編程規范檢測。
(2)BugDetective(C ++ Test 專利技術)。通過搜索代碼中的“可疑點”,開始分析正在測試的源碼??梢牲c是潛在的錯誤點。這些可疑點在Bug-Detective 規則中被定義。只要識別了可疑點,Bug-Detective 就調查導致該可疑點的可能執行路徑,并檢查是否有任何確實違反BugDetective 規則的路徑存在。如果找到了這樣的路徑,就報告一個違例。
(3)單元測試。用戶可根據需求,配置TestConfiguration,進行異常測試,功能測試,回歸測試。
(4)自動生成測試用例、驅動函數、樁函數。根據用戶配置的TestConfiguration,自動生成單元測試所需要的測試用例、驅動模塊、樁模塊,并且用戶可以添加、修改、刪除這些自動生成的模塊以達到精確測試的目的。
(5)TCM(團隊配置管理)和CVS(源碼控制器)。TCM 主要用于一個項目或者一個公司級的測試配置、抑制條件、規則文件和測試用例文件的共享,C++TEST 支持與CVS的連接來支持共享源碼和相關測試資源。
(6)GRS(組報告系統)。用于向項目管理者、軟件設計總師、軟件開發人員提供基于角色的報告。
做單元測試最大的問題就在于驅動函數和大量樁函數的編寫,這將占用測試人員大量的時間并且要求測試人員必須擁有比較豐富的編程經驗,現在,C++TEST 可以幫助我們完成這個復雜的工作。
其執行過程如下:“Generate Unit Tests”→“Generate Stubs”→“Build Test Exectable”→“Run Unit Test”,其中“Generate Unit Tests”產生驅動函數,“Generate Stubs”產生樁函數。所產生的驅動函數和樁函數均保存在用戶指定的工作空間內,可修改。
執行“Generate Stubs”后,可以從用戶指定的工作空間中找到C++TEST 自動產生的樁函數如圖1所示。

圖1 C++TEST 自動產生的樁函數
用C ++Test 對某型交換機的嵌入式系統(Vx-Works)運行程序(開發環境:Tornado2.2)進行靜態代碼測試。在系統環境變量下面添加PATH 變量的值如下:

從GUI 面板中直接導入Tornado 工程,方式如圖2所示。
然后執行:“Test Using”→“Builtin”→“Static Analysis”→“MISRA C++2008”。執行完成后察看C++TEST的違規報告如圖3 所示。
在C++Test的主面板中執行:“Test Using”→“Builtin”→“StaticAnalysis”→“BugDetective”。我們選擇的程序中包含以下的函數語句:



執行“BugDetecctive”后,C ++TEST 報告一個除0的違例。顯然,當min(x,y,m,n)函數的返回值為0時,出現除0的情況。該功能還能查找出使用未初始化內存、空指針解除引用、內存和資源泄露等問題。
執行嵌入式系統的單元測試過程如下:
(1)使用交叉編譯器,為目標平臺建立C ++TEST 運行時庫;
(2)配置C++TEST 使其可以在交叉編譯器和開發環境上工作;
(3)自定義測試流程定義;
(4)執行測試并使用C++TESE的GUI 來進行結果分析。
下面就Tornado2.0.2 編寫的一個簡單程序說明如何在C ++TEST 上執行嵌入式系統的單元測試。首先,從C++TEST的GUI 中導入一個Tornado項目,我們所使用的Tornado 源代碼如下:


在C++TEST的安裝目錄下找到pluginscom.parasoft.xtest.libs.cpp.win32.x86_7.2.10.34oswin32x86libsource arget 目錄下的WR_egcs_simnt_VxWorks5_4.mk 文件,然后查詢和修改相關變量,在主Mkefile 文件中找到了這個變量,并將其值修改為:WR_egcs_simnt_VxWorks5_4,然后查找PLATFORM 宏,并 在 主 Makefile 文 件 中 查 找CPPTEST_INC_DIR 變量,將其值定義為../../etc/include,然后將Tornado 安裝目錄中的make.exe 文件拷貝到主Makefile 文件所在的目錄并執行Make,如果編譯順利通過,可以在目標目錄下得到third_tornadoTest.out 文件,將這個文件拷貝到C ++TEST工作空間下的workspace.cpptest hird_tornadounit-datacurrent_tubf179707 目錄下,開啟Tornado的注冊器、目標服務器和仿真器,之后,在C ++TEST的GUI 中按照單元測試的步驟依次執行到“構建測試可執行文件”并執行:“Test Using”→“Builtin”→“Embedded Systems”→“Tornado”→“Load and Run Vxworks Test Object”。
回歸測試是在確認已知程序正確性的基礎上,為這些已知的正確程序生成一個叫做“回歸基”的測試套件。如果用戶更改了這個已知程序,比如:源碼修改、添加、刪除等,那么,可以運行已經生成的回歸基測試套件,C ++TEST 能自動捕獲測試輸出的不同點,并作為一個違例報告給用戶。如果所有的輸出都是相同的,則不會有違例報告產生。根據這個違例報告,可以確認用戶修改后的源代碼是否使以前的程序功能受到了影響。當我們對一個程序作了充分測試并修改后,執行“Test Using”→“Builtin”→“Unit Testing”→“Generate Regression Base”,就可以生成回歸基。以前的測試用例集和現在作為回歸基的測試用例集的區別:
沒有作為回歸基的測試用例集的函數格式為:
CPPTEST_POST_CONDITION_INTEGER("int_return",(_return)),其作用是:當這個測試用例執行完成后,在C++TEST的Console 面板中報告_return的值。
而作為回歸基的測試用例集的函數格式為:
CPPTEST_ASSERT_INTEGER_EQUAL(0,(_return)),其作用是:當這個測試用例完成后,比較_return 和0是否相等,如果相等,則不產生操作,如果不相等,則產生一個違例報告給用戶,其中的這個“0”值,就是在執行“Generate Regression Base”時,C++TEST 在執行該測試用例時所產生的值。然后C++TEST 把這個值作為執行這個測試用例的標準輸出,當用戶以這個回歸基為標準進行回歸測試時,C++TEST 就將這個標準輸出和進行回歸測試時得到的輸出作比較。
從圖4 中可以看出更改了函數內容后C ++Test 所報告的違例。

圖4 C++Test 所報告的違例
從兩個紅色方框可以很清楚地看到,當執行test_max_3()這個測試用例時,原來程序的返回值應該是1,更改后的程序返回值是0,所以C ++TEST 給出一個回歸測試的違例報告。
C++TEST 支持以下幾種覆蓋率分析:
Line Coverage:語句覆蓋。
Block Coverage:塊覆蓋。
Path Coverage:路徑覆蓋。
Decision Coverage:決策覆蓋。
Simple Condition Coverage:簡單條件覆蓋。
Modified Condition/Decision Coverage:修正的條件/決策覆蓋。
按照前面介紹的單元測試流程,執行一遍單元測試,查看C++TEST的Coverage 面板如圖5 所示。
以上是選擇Line Coverage 顯示的覆蓋率結果,同時,我們還可以選擇查看以其他方式統計的覆蓋率結果,如圖6 所示。


從C++TEST的主面板上查看源代碼的覆蓋率也是很方便的,它提供對已經覆蓋部分和未被覆蓋部分的不同顏色的高亮顯示。
由于C ++TEST 不檢測預處理語句、變量和函數定義等語句的覆蓋率,如int x=1;這樣的語句是不會有綠色的高亮顯示的。
用于用戶定義適合自己項目的測試配置,包括測試源的過濾(只對某些代碼進行測試,而另一些代碼不進行測試)、靜態代碼規范的選擇、產生測試用例的規則(產生測試用例的對象、方式,測試用例集存放的地點)、執行超時時間、外部符號表等內容,這里面的配置比較簡單,各種選項基本上都能見名知義,并且帶有通用性的配置選項不多,只需要按照用戶自己的需求進行選擇就行了。
C++TEST 作為一個以單元測試為主的測試工具,功能還是比較強大的。它的靜態編碼規范檢測內置的編碼規范有1456種,并且具有TCM 和Rule-Wrizad 功能。只需要一個比較了解該項目或者公司實際需要的編碼規范的人來制定相應的編碼規范,就可以在全公司范圍內得到應用和繼承。如果要做單元測試的話,利用它的這些功能,能極大地降低測試人員的工作量,還能降低出錯概率和調試時間。由于它具有“回歸基”測試套件的功能,在比較熟悉一個項目源代碼的情況下,用它來作回歸測試也是個相當不錯的選擇。同時,開發人員也可以運用這個功能作增量測試。
[1]Dorota Huizinga,Adam Kolawa.Automated Defect Prevention:Best Practices in Software Management [M].Wiley-Blackwell,2007.
[2]Adam Kolawa.The Next Leap in Productivity:What Top Managers Really Need to Know about Information Technology[M].Wiley,2009.
[3]Delores M Etter,Jeanine A Ingber.Engineering Problem Solving with C ++ (3rd Edition)[M].Prentice Hall,2011.
[4]D.S.Malik.C++ Programming:From Problem Analysis to Program Design[M].South-Western College Publishing,2012.
[5]Ana Colton- Sonnenberg.Computer- based Language Testing:C- Test Vs.Rapid Profile[M].GRIN Verlag oHG,2007.