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