張曉明
(中航西安飛機(jī)工業(yè)集團(tuán)股份有限公司,陜西 西安 710089)
隨著計算機(jī)技術(shù)在航空電子系統(tǒng)的不斷應(yīng)用,軟件的結(jié)構(gòu)也越來越復(fù)雜。在軟件整個生存周期中,隨著軟件開發(fā)的進(jìn)行,發(fā)現(xiàn)錯誤和修正錯誤的成本將越來越高,因此基于過程的測試尤為重要,而單元測試就是在編碼早期階段發(fā)現(xiàn)和修正錯誤的最好方法,可以提高軟件單元的質(zhì)量[1]。為了驗證軟件是否滿足預(yù)期功能,發(fā)現(xiàn)并解決軟件研制過程中的各種缺陷,優(yōu)化和進(jìn)一步提高軟件代碼質(zhì)量,僅靠軟件測試人員的人工統(tǒng)計分析已不能有效地對被測軟件作出準(zhǔn)確評價,迫切需要一種專業(yè)的軟件測試工具。
LDRA Testbed是專業(yè)的軟件驗證與確認(rèn)的質(zhì)量控制工具,具有靜態(tài)分析、數(shù)據(jù)流分析、動態(tài)分析和圖形化顯示等功能。該工具能夠顯著降低軟件缺陷,提升軟件的可靠性和健壯性,已廣泛應(yīng)用于國內(nèi)各研究所、大學(xué)和專業(yè)測試機(jī)構(gòu)。
軟件單元測試是對軟件基本組成單元進(jìn)行的測試[2]。單元測試的對象是模塊。模塊的特點有:具有唯一的標(biāo)識;具有明確的功能;擁有局部數(shù)據(jù);實現(xiàn)特定功能的算法;與其他模塊或外界存在數(shù)據(jù)聯(lián)系;可被其他模塊調(diào)用。
Testbed支持單個文件、多個文件(Set)和工程直接導(dǎo)入(Makefile)3種方式,可根據(jù)實際項目的需要進(jìn)行選擇,一般規(guī)模較小的選擇前兩種方式,規(guī)模較大的軟件應(yīng)選擇第三種方式。
序列是一組測試用例的集合,在不同的測試級別,如單元和集成測試,還具有隔離全局變量的作用,和其他測試工具如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在設(shè)置測試級別的時候,主要是設(shè)定打樁范圍,如單元測試可以對函數(shù)內(nèi)其他調(diào)用進(jìn)行打樁,序列中的測試用例單獨編譯,不共享全局變量;部件測試則針對該類或該文件之外的函數(shù)進(jìn)行打樁,序列中的測試用例是共享全局變量的;系統(tǒng)測試則可以針對序列或工程源文件之外的任意調(diào)用進(jìn)行打樁,序列中測試用例是共享全局變量的。
在運行測試用例之前,必須配置編譯命令和鏈接命令。編譯命令應(yīng)指定編譯器,并用“-I”選項指定依賴的頭文件,如要使用C++11標(biāo)準(zhǔn),編譯命令應(yīng)附加“-std=gnu++11”[3];鏈接命令應(yīng)使用“-L”選項指定依賴的庫文件。
Testbed在執(zhí)行測試用例時,根據(jù)具體情況需要添加打樁代碼,如該單元使用了一個類的對象,那就需要對類的構(gòu)造函數(shù)和析構(gòu)函數(shù)打樁,否則會直接報錯。針對多個測試用例共享的樁函數(shù),則需要進(jìn)行全局打樁。在全局打樁函數(shù)中,針對多個測試用例的不同實現(xiàn),可以利用Testbed的內(nèi)置變量ldra_qq_last_test_case、ldra_qq_test_case_number等進(jìn)行判斷區(qū)分。
系統(tǒng)函數(shù)一般不用打樁,直接調(diào)用即可,如果確有需求,也可以進(jìn)行打樁,打樁方法與普通函數(shù)完全一樣,可以自己定制系統(tǒng)函數(shù)功能,并可以標(biāo)記為系統(tǒng)樁函數(shù)(Testbed會生成函數(shù)別名),防止調(diào)用混亂出錯。
Tesdbed支持語句覆蓋(Statement Coverage)、分支/判定覆蓋(Branch/Decision Coverage)、分支條件覆蓋(Branch Condition Coverage)、條件組合覆蓋(Branch Condition Combination Coverage)、修改的條件判定覆蓋(MC/DC Coverage)、線性序列代碼及跳轉(zhuǎn)覆蓋(LCSAJ Coverage)以及DO-178B/C、ISO 26262等標(biāo)準(zhǔn)[4]。值得一提的LCSAJ覆蓋是LDRA特有的覆蓋分析,是對形成的線性代碼(start和finish配對)進(jìn)行覆蓋統(tǒng)計,消除了路徑覆蓋測試用例成幾何倍數(shù),僅需N+1(N為條件個數(shù))個測試用例即可達(dá)到100%覆蓋。覆蓋率配置可以在Testbed中進(jìn)行定義,如圖1所示。
圖1 覆蓋率配置
創(chuàng)建測試用例后,Testbed會自動識別出需要賦值的變量,并設(shè)置預(yù)期的返回值(false或true)。測試用例執(zhí)行符合預(yù)期會報告PASS,否則會報告FAIL,如報告FAIL說明函數(shù)的設(shè)計存在錯誤,需要進(jìn)行修改完善。Testbed在強(qiáng)灰盒模式是不分析覆蓋率的,因此如需要查看覆蓋率,單元測試時必須選擇輕灰盒模式。
某項目開發(fā)的MIL-STD-1553B總線仿真監(jiān)控軟件能夠?qū)崟r監(jiān)控航電系統(tǒng)中的1553B總線數(shù)據(jù),針對故障和異常狀態(tài)進(jìn)行報警,并能夠?qū)?shù)據(jù)進(jìn)行記錄和回放。該項目的軟件開發(fā)環(huán)境為:操作系統(tǒng)為Windows7;開發(fā)工具Qt5.8;開發(fā)語言為C++。本文以該項目中C1553.cpp中C1553:setFilter函數(shù)為例進(jìn)行單元測試分析。
本實例完整的編譯命令為:“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標(biāo)準(zhǔn),編譯選項必須帶有“-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”。
因為是針對類的函數(shù)測試,必然要調(diào)用類的構(gòu)造和析構(gòu)函數(shù),又因為是單元測試,所以必須對C1553::C1553()構(gòu)造函數(shù)和C1553::~C1553()析構(gòu)函數(shù)這兩個函數(shù)打樁。
創(chuàng)建第一個測試用例,Testbed自動會識別出bus、rt、sa、bFilter等變量,分別賦值為0、0、0、1,m_mapFilter為QMap對象,它的賦值方式為:{},設(shè)置預(yù)期返回值為false。測試用例執(zhí)行顯示PASS;創(chuàng)建第二個測試用例,其他賦值不變,設(shè)置預(yù)期返回值為true,測試用例執(zhí)行顯示FAIL,如圖2—3所示。
圖2 測試用例設(shè)計
圖3 測試用例執(zhí)行
編譯運行后,覆蓋率分析如圖4所示。覆蓋率分兩類,一個是本次測試用例的覆蓋,一個是累計的覆蓋統(tǒng)計。由圖4可以看到累計的語句覆蓋為68%,分支/判定覆蓋為50%,LCSAJ覆蓋為75%,需要繼續(xù)設(shè)計測試用例提升覆蓋率。
圖4 覆蓋率分析
本文以LCSAJ為例,介紹提高LCSAJ覆蓋率的方法。查看LCSAJ報告,共有4個LCSAJ,可以看到第3個LCSAJ沒有執(zhí)行,覆蓋率為75%也和上面的統(tǒng)計符合,如圖5所示。右鍵點擊查看覆蓋率流圖分析,其中實線是沒有執(zhí)行的路徑,雙擊第3個LCSAJ,如圖6所示。
圖5 LCSAJ覆蓋率報告
圖6 LCSAJ流圖分析
可以看到,Testbed已經(jīng)智能提示用戶應(yīng)該設(shè)置條件“itor !=m_mapFilter.end()”,即可滿足LCSAJ覆蓋。但由于m_mapFilter為QMap
圖7 累計覆蓋率分析
回歸測試指對軟件待測版本中相對上一個版本不變的特性進(jìn)行驗證[5],主要用于代碼發(fā)生更改,通過修改、復(fù)用原來的測試用例繼續(xù)對其進(jìn)行驗證,并且要求保證用例返回PASS。
Testbed中測試用例可以保存為TCF格式,導(dǎo)入原來的測試用例后,校驗測試用例是否仍然有效,測試用例圖標(biāo)會顯示綠色或紅色,綠色表明用例有效,即代碼更改后接口、類型等沒有改變;紅色表示用例失效,接口、類型等已發(fā)生變化。用例符合性報告如圖8所示。
圖8 用例校驗報告
針對已發(fā)生變化的測試用例,必須逐個修改測試用例的輸入、輸出以及返回值等,直到再次校驗測試用例全部通過。再次編譯執(zhí)行,直到全部用例返回PASS即可通過回歸測試。本例中修改完測試用例后,生成的回歸報告如圖9所示。
圖9 回歸報告
單元測試是白盒測試的主要手段。通過對軟件進(jìn)行有效的單元測試,可以幫助軟件開發(fā)及測試人員查看程序質(zhì)量結(jié)果。單元測試的目標(biāo)不是證明程序完全正確,而是盡可能多地發(fā)現(xiàn)軟件中的缺陷,提高軟件的可靠性和健壯性。本文基于LDRA Testbed詳細(xì)描述軟件單元測試的方法,并給出了具體實例。結(jié)果表明Testbed是一個功能強(qiáng)大且方便使用的軟件測試工具,可以節(jié)省資源、提高產(chǎn)品質(zhì)量、縮短開發(fā)時間,提供調(diào)整測試方案和優(yōu)化軟件測試的必要信息。