《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計(jì)應(yīng)用 > 面向集控嵌入式實(shí)時(shí)軟件的單元測(cè)試方法研究
面向集控嵌入式實(shí)時(shí)軟件的單元測(cè)試方法研究
2014年電子技術(shù)應(yīng)用第12期
裴承艷
(中國(guó)船舶重工集團(tuán)公司第七一〇研究所,湖北 宜昌443003)
摘要: 針對(duì)集控嵌入式實(shí)時(shí)軟件的組成和特點(diǎn),搭建了適合該軟件的仿真單元測(cè)試平臺(tái),并詳細(xì)介紹了基于Testbed對(duì)該軟件進(jìn)行單元測(cè)試的過程。依據(jù)靜態(tài)分析輸出的質(zhì)量度量模型值定量地評(píng)價(jià)了軟件內(nèi)在源碼的質(zhì)量,并基于圈復(fù)雜度度量值提出了一種優(yōu)先級(jí)的動(dòng)態(tài)分析測(cè)試策略,用監(jiān)控到的控制流信息來分析程序的覆蓋率,從而確保單元測(cè)試的充分性和有效性,提高測(cè)試效率,保證軟件的質(zhì)量。
中圖分類號(hào): TP311.5
文獻(xiàn)標(biāo)識(shí)碼: A
文章編號(hào): 0258-7998(2014)12-0125-04
Research on unit test methods of centralized control for embedded real-time software
Pei Chengyan
The 710 Research Institute,CSIC,Yichang 443003,China
Abstract: According to the characteristics and constitution of control console embedded real-time system software, a kind of simulating unit test platform about this system is built,and then the process of conducting unit test with testbed is detailed.Based on the value of quality output model of static analysis,we quantitatively evaluate the internal quality of the source code. Meanwhile, priority-based dynamic analysis testing strategy is properly proposed on the foundation of cyclomatic complexity.Monitored control flow information is used to analyze the coverage of programs, which is able to ensure adequacy and validity of unit test, and can improve test efficiency as well as software quality.
Key words : embedded real-time software;Testbed;static analysis;dynamic analysis;coverage

0 引言

  隨著信息化軍事技術(shù)的不斷深入,嵌入式實(shí)時(shí)軟件已在工業(yè)控制、電子信息以及武器裝備等系統(tǒng)中發(fā)揮著越來越重要的作用;同時(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)、訪問硬件麻煩,在開發(fā)環(huán)境下模擬整個(gè)系統(tǒng)存在困難性,這使得測(cè)試一直是個(gè)難點(diǎn),特別是單元測(cè)試,由于項(xiàng)目周期不允許,一些嵌入式軟件沒有進(jìn)行單元測(cè)試或單元測(cè)試不徹底;有些嵌入式軟件代碼具有較高的耦合性,使單元測(cè)試難以進(jìn)行;測(cè)試人員對(duì)于嵌入式軟件單元測(cè)試過于依賴自動(dòng)化測(cè)試工具,使測(cè)試效果不能令人滿意,測(cè)試不規(guī)范,效率低[3],且無法確保嵌入式軟件單元測(cè)試的充分性和有效性。

  針對(duì)上述問題,本文以集控嵌入式軟件為例,重點(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è)試過程,并基于圈復(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總線,通過CPU板上的兩路LAN接口與通信集控柜連接,完成與操舵臺(tái)、數(shù)采站、交流主配電柜、遙控操縱臺(tái)、綜控柜和顯控臺(tái)的網(wǎng)絡(luò)信息交換。CPU板上的一路RS422A接口與通信集控柜中的導(dǎo)航定位分機(jī)連接,完成導(dǎo)航定位信息的讀?。涣硪宦稲S422A接口與集控臺(tái)內(nèi)手控模塊連接,完成指令的轉(zhuǎn)發(fā)和手控狀態(tài)的傳輸??刂茊卧械腁D/DA板與左/右主機(jī)齒輪箱執(zhí)行器連接,完成速度調(diào)整。軟件的總體結(jié)構(gòu)圖如圖1所示。

001.jpg

  集控軟件使用C++/C語言編寫,程序基于模塊化思想設(shè)計(jì),在實(shí)時(shí)多任務(wù)操作系統(tǒng)VxWorks上實(shí)現(xiàn),基于Tornado的開發(fā)環(huán)境。按功能劃分模塊,采用多任務(wù)下的同步機(jī)制,通過消息實(shí)現(xiàn)各個(gè)模塊之間的通信。

  在該軟件的單元測(cè)試中,采用靜態(tài)分析和動(dòng)態(tài)測(cè)試相結(jié)合的方法來評(píng)估和完成軟件的充分性和測(cè)試的完備程度。

2 集控軟件測(cè)試關(guān)鍵步驟及實(shí)現(xiàn)

  2.1 基于Tornado的仿真單元測(cè)試環(huán)境搭建

  集控軟件單元測(cè)試工具采用的是Testbed,它是英國(guó)LDRA公司開發(fā)的一種軟件代碼測(cè)試及分析工具,主要用在軟件測(cè)試和軟件維護(hù)階段以便提高軟件產(chǎn)品的質(zhì)量,該工具可提供編碼規(guī)則檢查、軟件度量分析、數(shù)據(jù)流分析、覆蓋率分析等功能[5]。在Testbed /Tbrun工具下配置集控嵌入式軟件的仿真單元測(cè)試環(huán)境,需滿足在Tornado2.2集成開發(fā)環(huán)境下成功編譯、執(zhí)行測(cè)試驅(qū)動(dòng)程序,具體步驟如下:

  (1)借助Tbconfig工具完成Tornado2.2編譯環(huán)境的配置,并指定該開發(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)分析是通過工具在非運(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è)試過程和結(jié)果進(jìn)行詳細(xì)說明。

  2.2.1 靜態(tài)分析過程

002.jpg

003.jpg

  運(yùn)行測(cè)試工具Testbed,打開UdpSocket.cpp源程序,選擇MISRA編碼規(guī)則,然后在Select Analysis窗口下選擇分析菜單對(duì)該文件進(jìn)行靜態(tài)分析,通過該項(xiàng)分析,為測(cè)試人員提供了該文件中各函數(shù)之間的調(diào)用關(guān)系模型,圖2幫助測(cè)試人員簡(jiǎn)單明了地以顏色區(qū)分來顯示模塊間的調(diào)用關(guān)系,紅色為自定義函數(shù),綠色為系統(tǒng)函數(shù)。圖3是UdpSocket.cpp中各子函數(shù)通過度量的比例分析數(shù),可得出總函數(shù)的度量為91%,清晰性為 93%,可維護(hù)性為91%,測(cè)試性為100%。圖4是UdpSocket.cpp基于MaCabe的軟件度量模型對(duì)程序分析的Kiviat圖,每一軸代表一類度量元,被測(cè)試源代碼以扇形的結(jié)構(gòu)顯示出來,綠色表示符合質(zhì)量標(biāo)準(zhǔn)。圖5是UdpSocket.cpp基本節(jié)點(diǎn)數(shù)和基本圈復(fù)雜度數(shù)據(jù)分析柱狀圖。通過這些圖可以幫助測(cè)試人員了解代碼的靜態(tài)內(nèi)部信息,發(fā)現(xiàn)缺陷。

  2.2.2 靜態(tài)測(cè)試分析

  靜態(tài)分析的結(jié)果能夠幫助測(cè)試人員從代碼內(nèi)部結(jié)構(gòu)信息中開展工作,幫助質(zhì)量管理人員從軟件質(zhì)量度量中進(jìn)行質(zhì)量監(jiān)督[5]。通過對(duì)軟件靜態(tài)分析的總結(jié),可以從降低代碼的圈復(fù)雜度和提高代碼的注釋率兩方面提高軟件代碼質(zhì)量。

  (1)降低代碼的圈復(fù)雜度

  圈復(fù)雜度是應(yīng)用最廣泛的靜態(tà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文件中有判定語句:

  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。

  (2)提高代碼的注釋率

  提高代碼的注釋率可增加代碼的可讀性和可維護(hù)性,為每個(gè)代碼塊添加注釋,并在每一層使用統(tǒng)一的注釋方法和風(fēng)格,包括每個(gè)類和每個(gè)方法。

  2.3 集控實(shí)時(shí)嵌入式軟件的動(dòng)態(tài)測(cè)試

  2.3.1 測(cè)試用例設(shè)計(jì)

  (1)測(cè)試用例數(shù)據(jù)的合理設(shè)計(jì)

  測(cè)試用例的設(shè)計(jì)是為了提高測(cè)試代碼的覆蓋率,動(dòng)態(tài)測(cè)試中最重要的過程是如何設(shè)計(jì)測(cè)試用例,著重測(cè)試數(shù)據(jù)的輸入設(shè)計(jì)。對(duì)于一般標(biāo)準(zhǔn)類型的輸入變量(如int、char、float、double等)并沒有多大問題,當(dāng)變量是數(shù)組、指針、結(jié)構(gòu)體、VxWorks中的FUNCPTR、LOCAL等特殊類型時(shí),數(shù)據(jù)輸入就需要特別注意。當(dāng)數(shù)組的下標(biāo)值很大時(shí),進(jìn)行手工輸入是不可能的,可以在TBrun環(huán)境中有選擇地對(duì)需要的變量進(jìn)行賦值或者在插樁后的代碼中插入數(shù)組的初始化語句對(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的賦值語句:

  msgId=msgQGreate()//創(chuàng)建消息隊(duì)列

  在創(chuàng)建測(cè)試用例中對(duì)類型是MSG_Q_ID的變量輸入值應(yīng)設(shè)為msgQGreate()。

 ?。?)通過盡量少的測(cè)試用例達(dá)到盡量高的代碼覆蓋率。測(cè)試用例是以程序的內(nèi)部結(jié)構(gòu)為基礎(chǔ)來設(shè)計(jì)的,需要盡可能多地覆蓋程序的內(nèi)部邏輯結(jié)構(gòu)。

  2.3.2 測(cè)試驅(qū)動(dòng)的工作原理

  動(dòng)態(tài)測(cè)試過程中無法及時(shí)提供測(cè)試運(yùn)行所需的真正目標(biāo)機(jī)及其操作系統(tǒng),必須正確配置開啟仿真模擬器并將其作為虛擬目標(biāo)機(jī),將Testbed經(jīng)過編譯環(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è)試的過程。

  2.3.3 采用圈復(fù)雜度優(yōu)先級(jí)的動(dòng)態(tài)測(cè)試策略

  有效的測(cè)試策略可使軟件測(cè)試的效率最大化,從而滿足測(cè)試的各項(xiàng)要求并降低測(cè)試成本。由于基于Tornado開發(fā)環(huán)境的集控軟件代碼規(guī)模較大,功能模塊較多,結(jié)構(gòu)復(fù)雜,因此為了提高測(cè)試效率,制定了一種基于優(yōu)先級(jí)的動(dòng)態(tài)測(cè)試策略,具體步驟如下:

 ?。?)通過Testbed測(cè)試工具對(duì)每個(gè)文件靜態(tài)分析的結(jié)果從基本節(jié)點(diǎn)數(shù)和基本圈復(fù)雜度數(shù)據(jù)來分析柱狀圖,得到每一個(gè)文件中被測(cè)函數(shù)的圈復(fù)雜度和節(jié)點(diǎn)數(shù)。

  (2)按圈復(fù)雜度進(jìn)行高低排序,對(duì)圈復(fù)雜度高且重要的函數(shù)進(jìn)行重點(diǎn)測(cè)試。圖5可看出UdpSocket.cpp文件中SocketSndData()函數(shù)的圈復(fù)雜度最高,因此首先對(duì)該函數(shù)進(jìn)行重點(diǎn)測(cè)試。

 ?。?)編譯鏈接通過之后,執(zhí)行設(shè)計(jì)好的測(cè)試用例,用監(jiān)控到的控制流信息來分析程序的覆蓋率,依據(jù)分析結(jié)果不斷補(bǔ)充和優(yōu)化測(cè)試用例。根據(jù)各模塊的語句和分支覆蓋率、已執(zhí)行語句、執(zhí)行路徑以及未執(zhí)行的語句,判定覆蓋率并衡量是否完成動(dòng)態(tài)測(cè)試活動(dòng)。圖6為UdpSocket.cpp文件中SocketSndData()函數(shù)的動(dòng)態(tài)測(cè)試圖,圖右上角可以得到該函數(shù)的語句分支覆蓋率都為100%,圖左下角是設(shè)計(jì)并執(zhí)行通過的測(cè)試用例,右下角是用例數(shù)據(jù)的設(shè)計(jì)輸入。

005.jpg

3 結(jié)論

 ?。?)圖形界面框架類單元測(cè)試問題:由于Testbed工具自動(dòng)生成的測(cè)試驅(qū)動(dòng)入口是main()函數(shù),類似于控制臺(tái)程序,當(dāng)遇到圖形框架環(huán)境時(shí)無法完成測(cè)試??蚣茴悾ɡ鏜FC,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í),由于缺少庫文件,編譯不能通過,無法執(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è)試人員不能過于依賴測(cè)試工具:自動(dòng)化靜態(tài)分析存在一定的機(jī)械性,測(cè)試人員需逐項(xiàng)進(jìn)行分析確認(rè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] 陽凡林,康志忠.基于多維度覆蓋率的軟件測(cè)試動(dòng)態(tài)評(píng)價(jià)方法[J].軟件學(xué)報(bào),2008,21(9):2135-2146.


此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。