文獻(xiàn)標(biāo)識碼: A
文章編號: 0258-7998(2014)12-0125-04
0 引言
隨著信息化軍事技術(shù)的不斷深入,嵌入式實時軟件已在工業(yè)控制,、電子信息以及武器裝備等系統(tǒng)中發(fā)揮著越來越重要的作用,;同時隨著嵌入式軟件的規(guī)模和復(fù)雜性的不斷提高,作為有效保證和驗證軟件質(zhì)量的重要環(huán)節(jié)和依據(jù),,軟件測試已逐漸成為軟件研制成本最高的階段[1],。如何采用有效的嵌入式軟件工程化測試方法提高嵌入式軟件的質(zhì)量和可靠性以及增強(qiáng)軟件組織自身的軟件測試能力具有極其重要的意義。
錯誤越早發(fā)現(xiàn),項目付出的代價就越少,,單元測試作為軟件項目中最早介入的測試活動[2],,易于發(fā)現(xiàn)程序的錯誤和缺陷,也易于實現(xiàn)代碼測試的完全覆蓋,,因此單元測試的好壞對于軟件質(zhì)量的保證起著非常關(guān)鍵的作用,。然而由于嵌入式軟件的特殊性,如實時性強(qiáng),、與硬件緊密相關(guān),、訪問硬件麻煩,在開發(fā)環(huán)境下模擬整個系統(tǒng)存在困難性,,這使得測試一直是個難點,,特別是單元測試,由于項目周期不允許,,一些嵌入式軟件沒有進(jìn)行單元測試或單元測試不徹底,;有些嵌入式軟件代碼具有較高的耦合性,使單元測試難以進(jìn)行,;測試人員對于嵌入式軟件單元測試過于依賴自動化測試工具,,使測試效果不能令人滿意,測試不規(guī)范,,效率低[3],,且無法確保嵌入式軟件單元測試的充分性和有效性。
針對上述問題,,本文以集控嵌入式軟件為例,,重點研究了基于Testbed軟件測試工具的靜態(tài)分析和動態(tài)測試方法,提出了一種較為完整和可操作的單元測試解決方法,。研究分析了靜態(tài)分析輸出的度量模型值對嵌入式軟件的影響,,并根據(jù)度量值提出了提高軟件代碼質(zhì)量的措施;介紹了基于Tornado編譯環(huán)境的動態(tài)測試過程,并基于圈復(fù)雜度[4]提出了一種優(yōu)先級的動態(tài)分析測試策略,以確保單元測試的充分性和有效性,,提高軟件測試方法的效率和規(guī)范性,,確保軟件的質(zhì)量。
1 被測系統(tǒng)概述
被測系統(tǒng)集控軟件是一個實時嵌入式系統(tǒng),,運行在集控模塊控制單元內(nèi),,控制單元由底板、CPU板和AD/DA板組成,。板卡之間采用CPCI總線,通過CPU板上的兩路LAN接口與通信集控柜連接,,完成與操舵臺,、數(shù)采站、交流主配電柜、遙控操縱臺,、綜控柜和顯控臺的網(wǎng)絡(luò)信息交換,。CPU板上的一路RS422A接口與通信集控柜中的導(dǎo)航定位分機(jī)連接,完成導(dǎo)航定位信息的讀??;另一路RS422A接口與集控臺內(nèi)手控模塊連接,完成指令的轉(zhuǎn)發(fā)和手控狀態(tài)的傳輸,??刂茊卧械腁D/DA板與左/右主機(jī)齒輪箱執(zhí)行器連接,完成速度調(diào)整,。軟件的總體結(jié)構(gòu)圖如圖1所示,。
集控軟件使用C++/C語言編寫,程序基于模塊化思想設(shè)計,,在實時多任務(wù)操作系統(tǒng)VxWorks上實現(xiàn),,基于Tornado的開發(fā)環(huán)境。按功能劃分模塊,,采用多任務(wù)下的同步機(jī)制,,通過消息實現(xiàn)各個模塊之間的通信。
在該軟件的單元測試中,,采用靜態(tài)分析和動態(tài)測試相結(jié)合的方法來評估和完成軟件的充分性和測試的完備程度,。
2 集控軟件測試關(guān)鍵步驟及實現(xiàn)
2.1 基于Tornado的仿真單元測試環(huán)境搭建
集控軟件單元測試工具采用的是Testbed,它是英國LDRA公司開發(fā)的一種軟件代碼測試及分析工具,,主要用在軟件測試和軟件維護(hù)階段以便提高軟件產(chǎn)品的質(zhì)量,,該工具可提供編碼規(guī)則檢查、軟件度量分析,、數(shù)據(jù)流分析,、覆蓋率分析等功能[5]。在Testbed /Tbrun工具下配置集控嵌入式軟件的仿真單元測試環(huán)境,,需滿足在Tornado2.2集成開發(fā)環(huán)境下成功編譯,、執(zhí)行測試驅(qū)動程序,具體步驟如下:
(1)借助Tbconfig工具完成Tornado2.2編譯環(huán)境的配置,,并指定該開發(fā)環(huán)境的和測試工具的路徑,;
(2)配置生成被測函數(shù)的驅(qū)動模板C:\LDRA_Toolsuite\
Vxworks 路徑下的vxworks_Cshlayout_663.dat,該模板用于生成被測函數(shù)的測試驅(qū)動,;
(3)配置函數(shù)的插樁模板C:\Testbed760\Vxworks\Vxworks_
cinstr.dat,,插樁模板的作用是對被測函數(shù)的入口、出口,、控制流進(jìn)行插樁,,在單元測試結(jié)束時,,用于分析單元測試的覆蓋率,以確定測試用例是否滿足覆蓋率需求,。
2.2 集控實時嵌入式軟件的靜態(tài)分析
靜態(tài)分析是通過工具在非運行狀態(tài)下對程序結(jié)構(gòu),、數(shù)據(jù)結(jié)構(gòu)、代碼質(zhì)量的分析,,提取代碼大量的靜態(tài)內(nèi)部信息,,為代碼審查以及動態(tài)測試提供輔助參考的信息[5]。下面以集控軟件的網(wǎng)絡(luò)通信模塊UdpSocket.cpp為例,,對其靜態(tài)測試過程和結(jié)果進(jìn)行詳細(xì)說明,。
2.2.1 靜態(tài)分析過程
運行測試工具Testbed,打開UdpSocket.cpp源程序,,選擇MISRA編碼規(guī)則,,然后在Select Analysis窗口下選擇分析菜單對該文件進(jìn)行靜態(tài)分析,通過該項分析,,為測試人員提供了該文件中各函數(shù)之間的調(diào)用關(guān)系模型,,圖2幫助測試人員簡單明了地以顏色區(qū)分來顯示模塊間的調(diào)用關(guān)系,紅色為自定義函數(shù),,綠色為系統(tǒng)函數(shù),。圖3是UdpSocket.cpp中各子函數(shù)通過度量的比例分析數(shù),可得出總函數(shù)的度量為91%,,清晰性為 93%,,可維護(hù)性為91%,測試性為100%,。圖4是UdpSocket.cpp基于MaCabe的軟件度量模型對程序分析的Kiviat圖,,每一軸代表一類度量元,被測試源代碼以扇形的結(jié)構(gòu)顯示出來,,綠色表示符合質(zhì)量標(biāo)準(zhǔn),。圖5是UdpSocket.cpp基本節(jié)點數(shù)和基本圈復(fù)雜度數(shù)據(jù)分析柱狀圖。通過這些圖可以幫助測試人員了解代碼的靜態(tài)內(nèi)部信息,,發(fā)現(xiàn)缺陷,。
2.2.2 靜態(tài)測試分析
靜態(tài)分析的結(jié)果能夠幫助測試人員從代碼內(nèi)部結(jié)構(gòu)信息中開展工作,幫助質(zhì)量管理人員從軟件質(zhì)量度量中進(jìn)行質(zhì)量監(jiān)督[5],。通過對軟件靜態(tài)分析的總結(jié),,可以從降低代碼的圈復(fù)雜度和提高代碼的注釋率兩方面提高軟件代碼質(zhì)量。
?。?)降低代碼的圈復(fù)雜度
圈復(fù)雜度是應(yīng)用最廣泛的靜態(tài)度量之一,,用來衡量一個函數(shù)判定結(jié)構(gòu)的復(fù)雜程度,圈復(fù)雜度公式V(G)=P+1,,P是代碼中判定結(jié)點的數(shù)量[6],。程序的可能存在錯誤數(shù)和圈復(fù)雜度有著很大的相關(guān)性,,圈復(fù)雜度越大代表程序代碼的質(zhì)量低并且難以維護(hù)和測試[6],。
當(dāng)代碼中遇到判定條件比較復(fù)雜時,,可以將判定條件的表達(dá)式提前計算存儲在一個變量中,簡化判斷條件,,減低代碼的圈復(fù)雜度,,減少bug數(shù)。例如UdpSocket.cpp文件中有判定語句:
If ((UNIT)(szTemp[0] == 0xA5 && (UNIT)(szTemp[1]
== 0xA5) && (UNIT)(szTemp[2] == 0xA3))
{
}
該判定條件的判定結(jié)點為3,,圈復(fù)雜度即為4,,將代碼優(yōu)化之后如下:
int num;
num=(UNIT)(szTemp[0] == 0xA5 && (UNIT)(szTemp[1] == 0xA5) && (UNIT)(szTemp[2] == 0xA3);
if (num)
{
}
優(yōu)化后的代碼判定結(jié)點為1,圈復(fù)雜度為2,。
?。?)提高代碼的注釋率
提高代碼的注釋率可增加代碼的可讀性和可維護(hù)性,為每個代碼塊添加注釋,,并在每一層使用統(tǒng)一的注釋方法和風(fēng)格,,包括每個類和每個方法。
2.3 集控實時嵌入式軟件的動態(tài)測試
2.3.1 測試用例設(shè)計
?。?)測試用例數(shù)據(jù)的合理設(shè)計
測試用例的設(shè)計是為了提高測試代碼的覆蓋率,,動態(tài)測試中最重要的過程是如何設(shè)計測試用例,著重測試數(shù)據(jù)的輸入設(shè)計,。對于一般標(biāo)準(zhǔn)類型的輸入變量(如int,、char、float,、double等)并沒有多大問題,,當(dāng)變量是數(shù)組、指針,、結(jié)構(gòu)體,、VxWorks中的FUNCPTR、LOCAL等特殊類型時,,數(shù)據(jù)輸入就需要特別注意,。當(dāng)數(shù)組的下標(biāo)值很大時,進(jìn)行手工輸入是不可能的,,可以在TBrun環(huán)境中有選擇地對需要的變量進(jìn)行賦值或者在插樁后的代碼中插入數(shù)組的初始化語句對整個數(shù)組進(jìn)行賦值,;當(dāng)變量是指針時,由于不能給指針直接賦地址,,輸入指針采用映射的方法將指針變量映射成相應(yīng)的自定義變量作為指針的輸入值,;結(jié)構(gòu)體變量賦值不正確時很容易導(dǎo)致測試用例跑飛掉,需要從源代碼找到該變量創(chuàng)建的賦值函數(shù),,將該函數(shù)作為變量的輸入值,,必要時還需要添加函數(shù)的參數(shù),,例如本文需測試的文件CUdpSocket.cpp中有消息隊列數(shù)據(jù)結(jié)構(gòu)體:
MSG_Q_ID msgId//接收消息的消息隊列ID號
其中MSG_Q_ID屬于VxWorks的系統(tǒng)調(diào)用,在文件中有對msgId的賦值語句:
msgId=msgQGreate()//創(chuàng)建消息隊列
在創(chuàng)建測試用例中對類型是MSG_Q_ID的變量輸入值應(yīng)設(shè)為msgQGreate(),。
?。?)通過盡量少的測試用例達(dá)到盡量高的代碼覆蓋率。測試用例是以程序的內(nèi)部結(jié)構(gòu)為基礎(chǔ)來設(shè)計的,,需要盡可能多地覆蓋程序的內(nèi)部邏輯結(jié)構(gòu),。
2.3.2 測試驅(qū)動的工作原理
動態(tài)測試過程中無法及時提供測試運行所需的真正目標(biāo)機(jī)及其操作系統(tǒng),必須正確配置開啟仿真模擬器并將其作為虛擬目標(biāo)機(jī),,將Testbed經(jīng)過編譯環(huán)境鏈接后生成的測試驅(qū)動程序下載到仿真模擬器中運行,。每執(zhí)行一個測試用例需要重新編譯和執(zhí)行,函數(shù)的驅(qū)動程序是由Testbed/Tbrun根據(jù)驅(qū)動模板自動生成的,,驅(qū)動程序是一個基于控制臺的程序,,主要完成動態(tài)測試環(huán)境初始化,當(dāng)調(diào)用測試用例時要執(zhí)行函數(shù)ldra_qq_execute_test_
case_1(),,該函數(shù)負(fù)責(zé)被測函數(shù)入口參數(shù)的初始化,,然后再調(diào)用被測函數(shù)完成整個測試的過程。
2.3.3 采用圈復(fù)雜度優(yōu)先級的動態(tài)測試策略
有效的測試策略可使軟件測試的效率最大化,,從而滿足測試的各項要求并降低測試成本,。由于基于Tornado開發(fā)環(huán)境的集控軟件代碼規(guī)模較大,功能模塊較多,,結(jié)構(gòu)復(fù)雜,,因此為了提高測試效率,制定了一種基于優(yōu)先級的動態(tài)測試策略,,具體步驟如下:
?。?)通過Testbed測試工具對每個文件靜態(tài)分析的結(jié)果從基本節(jié)點數(shù)和基本圈復(fù)雜度數(shù)據(jù)來分析柱狀圖,得到每一個文件中被測函數(shù)的圈復(fù)雜度和節(jié)點數(shù),。
?。?)按圈復(fù)雜度進(jìn)行高低排序,對圈復(fù)雜度高且重要的函數(shù)進(jìn)行重點測試,。圖5可看出UdpSocket.cpp文件中SocketSndData()函數(shù)的圈復(fù)雜度最高,,因此首先對該函數(shù)進(jìn)行重點測試。
?。?)編譯鏈接通過之后,,執(zhí)行設(shè)計好的測試用例,用監(jiān)控到的控制流信息來分析程序的覆蓋率,,依據(jù)分析結(jié)果不斷補(bǔ)充和優(yōu)化測試用例,。根據(jù)各模塊的語句和分支覆蓋率、已執(zhí)行語句,、執(zhí)行路徑以及未執(zhí)行的語句,,判定覆蓋率并衡量是否完成動態(tài)測試活動,。圖6為UdpSocket.cpp文件中SocketSndData()函數(shù)的動態(tài)測試圖,圖右上角可以得到該函數(shù)的語句分支覆蓋率都為100%,,圖左下角是設(shè)計并執(zhí)行通過的測試用例,,右下角是用例數(shù)據(jù)的設(shè)計輸入。
3 結(jié)論
?。?)圖形界面框架類單元測試問題:由于Testbed工具自動生成的測試驅(qū)動入口是main()函數(shù),,類似于控制臺程序,,當(dāng)遇到圖形框架環(huán)境時無法完成測試,。框架類(例如MFC,NI)應(yīng)用程序的執(zhí)行是以事件驅(qū)動面向?qū)ο蟮慕Y(jié)構(gòu),,定義了很多的API,,應(yīng)用程序可以直接調(diào)用。兩種結(jié)構(gòu)是完全不同的,,當(dāng)直接使用測試工具生成測試驅(qū)動時,,由于缺少庫文件,編譯不能通過,,無法執(zhí)行測試用例進(jìn)行測試,。
(2)被測單元代碼的必要修改:雖然大多數(shù)編譯環(huán)境和Testbed工具關(guān)聯(lián)在一起,,但有一些代碼單元還是不能直接執(zhí)行測試,,代碼在動態(tài)測試之前必須做適當(dāng)?shù)男薷模热缫恍┲袛嗪瘮?shù),、死循環(huán)while()以及Forever等,。
(3)測試人員不能過于依賴測試工具:自動化靜態(tài)分析存在一定的機(jī)械性,,測試人員需逐項進(jìn)行分析確認(rèn)出真正的問題所在,,有效的測試不能簡單的依靠測試工具。
參考文獻(xiàn)
[1] 丁旭,,崔吉崗,,劉春裕.軍用嵌入式軟件結(jié)構(gòu)覆蓋測試技術(shù)[J].指揮控制與仿真,2008,,30(3):120-122.
[2] 李金麒,,徐建平.嵌入式系統(tǒng)軟件可靠性設(shè)計與測試方法[J].計算機(jī)系統(tǒng)應(yīng)用,2013,,22(1):74-78.
[3] 肖波.通訊系統(tǒng)嵌入式平臺下的單元測試技術(shù)研究[D].上海:華東師范大學(xué),,2005.
[4] 孫夢磷,宋曉秋,,巢翌.軟件程序代碼質(zhì)量度量技術(shù)研究[J].計算機(jī)工程與設(shè)計,,2006,,27(2):325-327.
[5] 張大林.基于缺陷關(guān)聯(lián)的靜態(tài)分析優(yōu)化[J].軟件學(xué)報,2014,,25(2):386-399.
[6] 陽凡林,,康志忠.基于多維度覆蓋率的軟件測試動態(tài)評價方法[J].軟件學(xué)報,2008,,21(9):2135-2146.