張曉明
(中航西安飛機工業集團股份有限公司,陜西 西安 710089)
隨著計算機技術在航空電子系統的不斷應用,軟件的結構也越來越復雜。在軟件整個生存周期中,隨著軟件開發的進行,發現錯誤和修正錯誤的成本將越來越高,因此基于過程的測試尤為重要,而單元測試就是在編碼早期階段發現和修正錯誤的最好方法,可以提高軟件單元的質量[1]。為了驗證軟件是否滿足預期功能,發現并解決軟件研制過程中的各種缺陷,優化和進一步提高軟件代碼質量,僅靠軟件測試人員的人工統計分析已不能有效地對被測軟件作出準確評價,迫切需要一種專業的軟件測試工具。
LDRA Testbed是專業的軟件驗證與確認的質量控制工具,具有靜態分析、數據流分析、動態分析和圖形化顯示等功能。該工具能夠顯著降低軟件缺陷,提升軟件的可靠性和健壯性,已廣泛應用于國內各研究所、大學和專業測試機構。
軟件單元測試是對軟件基本組成單元進行的測試[2]。單元測試的對象是模塊。模塊的特點有:具有唯一的標識;具有明確的功能;擁有局部數據;實現特定功能的算法;與其他模塊或外界存在數據聯系;可被其他模塊調用。
Testbed支持單個文件、多個文件(Set)和工程直接導入(Makefile)3種方式,可根據實際項目的需要進行選擇,一般規模較小的選擇前兩種方式,規模較大的軟件應選擇第三種方式。
序列是一組測試用例的集合,在不同的測試級別,如單元和集成測試,還具有隔離全局變量的作用,和其他測試工具如C++Test中的測試套件功能類似。
Testbed支持6種測試級別:
(1)Instrumentation No Coverage:不帶覆蓋率分析的集成測試;
(2)Code Coverage Only:帶覆蓋率分析的集成測試;
(3)Module Testing-Isolate Procedures &Generate Code Coverage(Light Grey Box):帶覆蓋率分析的部件測試;
(4)Module Testing-Isolate Procedures(Dark Grey Box):不帶覆蓋率分析的部件測試;
(5)Unit Testing-Isolate Procedures &Generate Code Coverage(Pale Grey Box):帶覆蓋率分析的單元測試;
(6)Unit Testing-Isolate Procedures(Strong Grey Box):不帶覆蓋率分析的單元測試。
Testbed在設置測試級別的時候,主要是設定打樁范圍,如單元測試可以對函數內其他調用進行打樁,序列中的測試用例單獨編譯,不共享全局變量;部件測試則針對該類或該文件之外的函數進行打樁,序列中的測試用例是共享全局變量的;系統測試則可以針對序列或工程源文件之外的任意調用進行打樁,序列中測試用例是共享全局變量的。
在運行測試用例之前,必須配置編譯命令和鏈接命令。編譯命令應指定編譯器,并用“-I”選項指定依賴的頭文件,如要使用C++11標準,編譯命令應附加“-std=gnu++11”[3];鏈接命令應使用“-L”選項指定依賴的庫文件。
Testbed在執行測試用例時,根據具體情況需要添加打樁代碼,如該單元使用了一個類的對象,那就需要對類的構造函數和析構函數打樁,否則會直接報錯。針對多個測試用例共享的樁函數,則需要進行全局打樁。在全局打樁函數中,針對多個測試用例的不同實現,可以利用Testbed的內置變量ldra_qq_last_test_case、ldra_qq_test_case_number等進行判斷區分。
系統函數一般不用打樁,直接調用即可,如果確有需求,也可以進行打樁,打樁方法與普通函數完全一樣,可以自己定制系統函數功能,并可以標記為系統樁函數(Testbed會生成函數別名),防止調用混亂出錯。
Tesdbed支持語句覆蓋(Statement Coverage)、分支/判定覆蓋(Branch/Decision Coverage)、分支條件覆蓋(Branch Condition Coverage)、條件組合覆蓋(Branch Condition Combination Coverage)、修改的條件判定覆蓋(MC/DC Coverage)、線性序列代碼及跳轉覆蓋(LCSAJ Coverage)以及DO-178B/C、ISO 26262等標準[4]。值得一提的LCSAJ覆蓋是LDRA特有的覆蓋分析,是對形成的線性代碼(start和finish配對)進行覆蓋統計,消除了路徑覆蓋測試用例成幾何倍數,僅需N+1(N為條件個數)個測試用例即可達到100%覆蓋。覆蓋率配置可以在Testbed中進行定義,如圖1所示。

圖1 覆蓋率配置
創建測試用例后,Testbed會自動識別出需要賦值的變量,并設置預期的返回值(false或true)。測試用例執行符合預期會報告PASS,否則會報告FAIL,如報告FAIL說明函數的設計存在錯誤,需要進行修改完善。Testbed在強灰盒模式是不分析覆蓋率的,因此如需要查看覆蓋率,單元測試時必須選擇輕灰盒模式。
某項目開發的MIL-STD-1553B總線仿真監控軟件能夠實時監控航電系統中的1553B總線數據,針對故障和異常狀態進行報警,并能夠對數據進行記錄和回放。該項目的軟件開發環境為:操作系統為Windows7;開發工具Qt5.8;開發語言為C++。本文以該項目中C1553.cpp中C1553:setFilter函數為例進行單元測試分析。
本實例完整的編譯命令為:“g++"$(Name)"-o "$(Exe)"-I $(SourcedirQuoteUnEnv) $(IncludedirsLeadQuoteUnEnv)-Idebug-ID:QtQt5.8.0·.8mingw53_32include-ID:QtQt5.8.05.8mingw53_32includeQtCore-ID:QtQt5.8.05.8mingw53_32includeQtGui-ID:QtQt5.8.05.8mingw53_32includeQtWidgets-std=gnu++11”。注意由于該項目使用了Qt5.8,采用了C++11標準,編譯選項必須帶有“-std=gnu++11”。
本實例完整的鏈接命令:“g++*.o-o "$(Exe)"-lmingw32-LD:QtQt5.8.05.8mingw53_32lib-lshell32-LD:projectDiagnosis1553-lbusapi32 d D:QtQt5.8.05.8mingw53_32liblibQt5Widgetsd.a D:QtQt5.8.05.8mingw53_32liblibQt5Guid.a D:QtQt5.8.05.8mingw53_32liblibQt5Cored.a”。
因為是針對類的函數測試,必然要調用類的構造和析構函數,又因為是單元測試,所以必須對C1553::C1553()構造函數和C1553::~C1553()析構函數這兩個函數打樁。
創建第一個測試用例,Testbed自動會識別出bus、rt、sa、bFilter等變量,分別賦值為0、0、0、1,m_mapFilter為QMap對象,它的賦值方式為:{},設置預期返回值為false。測試用例執行顯示PASS;創建第二個測試用例,其他賦值不變,設置預期返回值為true,測試用例執行顯示FAIL,如圖2—3所示。

圖2 測試用例設計

圖3 測試用例執行
編譯運行后,覆蓋率分析如圖4所示。覆蓋率分兩類,一個是本次測試用例的覆蓋,一個是累計的覆蓋統計。由圖4可以看到累計的語句覆蓋為68%,分支/判定覆蓋為50%,LCSAJ覆蓋為75%,需要繼續設計測試用例提升覆蓋率。

圖4 覆蓋率分析
本文以LCSAJ為例,介紹提高LCSAJ覆蓋率的方法。查看LCSAJ報告,共有4個LCSAJ,可以看到第3個LCSAJ沒有執行,覆蓋率為75%也和上面的統計符合,如圖5所示。右鍵點擊查看覆蓋率流圖分析,其中實線是沒有執行的路徑,雙擊第3個LCSAJ,如圖6所示。

圖5 LCSAJ覆蓋率報告

圖6 LCSAJ流圖分析
可以看到,Testbed已經智能提示用戶應該設置條件“itor !=m_mapFilter.end()”,即可滿足LCSAJ覆蓋。但由于m_mapFilter為QMap

圖7 累計覆蓋率分析
回歸測試指對軟件待測版本中相對上一個版本不變的特性進行驗證[5],主要用于代碼發生更改,通過修改、復用原來的測試用例繼續對其進行驗證,并且要求保證用例返回PASS。
Testbed中測試用例可以保存為TCF格式,導入原來的測試用例后,校驗測試用例是否仍然有效,測試用例圖標會顯示綠色或紅色,綠色表明用例有效,即代碼更改后接口、類型等沒有改變;紅色表示用例失效,接口、類型等已發生變化。用例符合性報告如圖8所示。

圖8 用例校驗報告
針對已發生變化的測試用例,必須逐個修改測試用例的輸入、輸出以及返回值等,直到再次校驗測試用例全部通過。再次編譯執行,直到全部用例返回PASS即可通過回歸測試。本例中修改完測試用例后,生成的回歸報告如圖9所示。

圖9 回歸報告
單元測試是白盒測試的主要手段。通過對軟件進行有效的單元測試,可以幫助軟件開發及測試人員查看程序質量結果。單元測試的目標不是證明程序完全正確,而是盡可能多地發現軟件中的缺陷,提高軟件的可靠性和健壯性。本文基于LDRA Testbed詳細描述軟件單元測試的方法,并給出了具體實例。結果表明Testbed是一個功能強大且方便使用的軟件測試工具,可以節省資源、提高產品質量、縮短開發時間,提供調整測試方案和優化軟件測試的必要信息。