1 概述
軟體測試是很廣的概念。從其貫穿軟體生命週期全過程來看,測試可分為模組測試、整合測試、系統測試等階段。測試還可分為靜態檢查和動態運行測試兩大類。在動態運行測試中,又可有基於程式結構的白盒測試(或稱為覆蓋測試)和基於功能的黑箱測試。測試不僅關注程式的功能,還有性有測試、強度測試等等。
要達到比較好的測試效果,除了要有周全的測試計劃、可控的測試過程、測試人員豐富的經驗外,還需要藉助一些行之有效協助工具輔助,尤其在當今軟體規模日益龐大、測試工作量成倍增加的情況下。對應上述的測試分類情況,測試載入器可劃分為:支援對程式原始碼進行靜態規則檢查和品質評估的靜態分析工具、支援對程式單元進行動態覆蓋測試的工具、對軟體系統的整體運行效能進行測試的工具。另外,還有一些特殊用途的或專用工具,如協議測試儀、記憶體偵查工具等。這些工具都有較為成熟的商業化產品,也可通過自行開發的方式獲得。
本文具體討論了對一類特殊的系統軟體——嵌入式即時作業系統——進行覆蓋測試的情況。內容涉及對這類軟體特性的研究、測試的痛點和特點、對現有測試載入器的適應性改造和測試執行個體說明。
2 軟體覆蓋測試
覆蓋是一種白盒測試方法,測試人員必須擁有程式的規格說明和程式清單,以程式的內部結構為基礎,來設計測試案例。其基本準則是則測試案例來儘可能多地覆蓋程式的內部邏輯結構,發現其中的錯誤和問題。所以,覆蓋測試一般應用在軟體測試的早期,即單元測試階段。
覆蓋的幾種方法或策略如表1所列。
表1 幾種典型的覆蓋策略
覆蓋策略 |
定 義 |
語句覆蓋 |
在制定測試案例時,使程式中的每個語句都至少執行1次。其缺點是不能發現某些邏輯錯誤 |
判定覆蓋 |
執行足夠的測試案例,使得程式中每個判定都獲得一次“真”值和“假”值,或者說使每一個分支都至少通過1次 |
條件覆蓋 |
執行足夠的測試案例,使得判定中的每個條件獲得各種可能的結果 |
判定/條件覆蓋 |
執行足夠的測試案例,使得判定中的每個條件取得各種可能的值,並使得每個判定取得各種可能的結果 |
條件組合覆蓋 |
執行足夠的測試案例,使得每個判定中的條件的各種組合都至少出現1次。其特點是覆蓋較充分,滿足條件組合覆蓋的測試案例也一定滿足判定覆蓋、條件覆蓋和判定/條件覆蓋。 |
從以上簡要介紹可看出,這幾種覆蓋策略的嚴格程式有如下趨勢:
其它一些覆蓋策略還包括:修改的條件/判斷覆蓋(通常簡稱為MCDC)、路徑覆蓋、函數覆蓋、調用覆蓋、線性代碼順序和跳轉覆蓋、資料流覆蓋、目標代碼分支覆蓋、迴圈覆蓋、關係操作符覆蓋等。隨著軟體規模的增長,實現全面的覆蓋所需的測試案例的數目也越來越龐大,因此根據被測軟體對象的特點選擇適當的覆蓋策略是非常重要的;同時,要確定合理測試目標,達到100%的覆蓋往往要付出很大的代價,應該同形式化評審等方法結合,以發現更多的軟體故障。
3 覆蓋測試載入器
要取得較好的覆蓋測試效果,需要藉助一定的工具軟體。這些工具軟體一般具備如下的功能特點,可彌補人為測試的缺陷:
①分析軟體內部結構,協助制定覆蓋策略及設計測試案例;
②與適當的編譯器結合,對被測軟體實施自動插裝,以便在其運行過程中產生覆蓋資訊並收集這些資訊;
③根據搜集的覆蓋資訊計算覆蓋率,協助測試人員找到未被覆蓋的軟體部位,以改進測試案例提高覆蓋率。
在利用工具進行動態覆蓋測試時,需要3個要素:測試案例、插裝過的被測代碼、搜集覆蓋資訊並進行分析的工具本身。代碼插裝由工具自動完成,通過執行測試案例,再由工具搜集覆蓋資訊並進行分析,就可以看到覆蓋率指標了。圖1展示實現覆蓋測試的基本過程。
4 嵌入式軟體的覆蓋測試原理
嵌入式軟體的開發與通用軟體很大的不同點在於,需要採用交叉開發的方式:開發工具運行在軟硬體設定豐富的宿主機上,而嵌入式應用程式運行在軟硬體資源相對缺乏的目標機上。對於這類軟體的測試也存在著同樣的問題:測試載入器運行在宿主機上,測試所需要的資訊在目標機上產生,並通過一定的物理/邏輯串連傳輸到縮主機上,由測試載入器接收。因此,嵌入式軟體測試的一個重要問題是建立宿主機與目標機之間的物理/邏輯串連,解決資料資訊的傳輸問題。
嵌入式軟體覆蓋測試的基本原理2所示。
在目標機方,插裝過的被測應用程式將覆蓋資訊發送到訊息佇列中,一個專門的任務負責在適當的時候將這些資訊發送到宿主機方。縮主機方有專門的模組負責接收覆蓋資訊。並交給分析工具分析和線上動態顯示覆蓋率的增長情況。
支援嵌入式軟體覆蓋測試的工具應解決如下2方面的關鍵問題:
*與嵌入式作業系統的結合
覆蓋測試載入器與嵌入式作業系統的結合體現在3方面。首先,在目標機方,應用任務與專門負責收集/上傳覆蓋資訊的任務是通過訊息佇列來傳遞資料的,該訊息佇列可使用嵌入式作業系統的相應機制實現。其次,這個專門任務也可以被看作一個特殊的應用任務,也必須有嵌入式作業系統的支援,因為任務管理是後者的準系統之一。最後,目標機與宿主機之間的通訊可以採用串口或乙太網路方式,對串口的驅動或網路通訊協定均可使用嵌入式作業系統的相應程式組件。
*與其它嵌入式交叉開發工具的關係
嵌入式應用程式的開發通常採用交叉開發方式,幾乎所有的開發工具均要解決3部分的問題:宿主機部分的功能、目標機部分的功能、宿主機與目標機的串連問題。其中,宿主機與目標機的串連是個瓶頸,如果不同的工具要使用同一物理線路實現資料轉送,則要解決對該物理線路(或者說硬體連接埠)的正確共用。比如在圖3所示的環境中,宿主機方的各種工具通過統一的介面——目標伺服器(target server)實現對通訊線路的訪問,目標機方的調試代理(debug agent)則是各種資訊(調試資訊、覆蓋資訊、時間資訊、對象資訊等)的收集與傳遞的核心。
5 Logiscope在嵌入式作業系統DeltaCORE測試中的應用
Logiscope是Verilog公司的CASE產品,對軟體的編碼、測試、維護提供多方面的服務,並且支援嵌入式軟體的覆蓋測試。
5.1 測試前的準備
測試前的準備即為支援對DeltaCORE的測試所做的移植工作。
目前,Logiscope已經為一些成熟的商用嵌入式作業系統提供了支援,比如pSOS。DeltaCORE是我國自主開發的嵌入式強即時作業系統核心,為了利用Logiscope實現對DeltaCORE的應用程式乃至DeltaCORE本身的測試,我們主要解決了第4節中描述的第1個關鍵問題。
為了支援嵌入式程式的測試,Logiscope提供了運行在目標機方的程式碼(或稱為目標機端的支援庫),裡麵包含了:
*1個用來收集和發送覆蓋資訊的主迴圈線程,該線程即是嵌入式應用中的特殊任務;
*實現具體資料轉送的函數,包括對串口或網路的驅動,它們將被上述線程調用;
*插裝函數的實現,這些函數被被測代碼調用,向緩衝中放入覆蓋訊息塊;
*對緩衝資訊隊列的管理;
*初始化代碼。
例如,當被測程式運行進入到一條if(……)語句時,整個過程4所示。
為了支援對DeltaCORE的測試,將與這些機制相關的代碼進行移植,包括以下幾方面:
*將收集和發送覆蓋資訊的主迴圈線程作為在目標機端啟動並執行應用程式中的特殊任務;
*對串口的驅動採用LambdaTOOL BSP(板級支援包)中的串口驅動代替,對網路的驅動,用DeltaCORE的配套組件DeltaNET中的驅動程式實現;
*利用DeltaCORE的信箱機制實現訊息佇列的建立和管理,插裝代碼向這些信箱發送覆蓋訊息塊;
*在DetaCORE應用程式的根任務中調用Logiscope的初始化函數,達到建立特殊任務信箱的目的。
開發DeltaCORE應用程式時,我們使用了其配套開發工具LambdaTOOL。由於所使用的工具版本沒有實現目標伺服器(target server)的調試方式,因此對物理連接埠的使用採用的獨佔方式,即調試工具不能與其它工具共用同一連接埠。我們可以用網路試上傳並啟動目標應用程式,而通過串口傳送覆蓋資訊。
5.2 對DeltaCORE的覆蓋測試過程及結果
對於函數內部,Logiscope支援的覆蓋策略有:
*指令塊IBs(Instruction Blocks)
*判斷到判斷的路徑DDPs(Decision-to-Decision Paths)
*MCDC(Modified Condition/Decision)
在項目層次上支援的覆蓋策略是:
*過程到過程路徑PPP(Procedure-to-Procedure Path)
在DeltaCORE的測試中,我們採用了較為常用的覆蓋策略——判斷到判斷的路徑,其含義是:DDP是一個指令序列,它的起點是函數或判斷(if,while,……)的進入點,它的出口是下一個函數或判斷的退出點,之間不能再有判斷,比如在圖5中包含了5個DDPs:
測試的具體過程是:
①利用插裝分析器對DeltaCORE的原始碼進行插裝,並產生插裝資訊檔。
②將移植後的Logiscope目標機端程式與插裝後的核心原始碼一同編譯連結成庫,以替代原來的核心庫,供應用程式使用。
③編寫測試案例,從實現應用的角度使用DeltaCORE的各種系統功能調用,力求遍曆核心功能所有的判定分支,並將這些案例編譯成可執行程式。
④在宿主機端啟動覆蓋資訊收集和剖析器,用LambdaTOOL的調試器下載並啟動應用程式。DeltaCORE的覆蓋資訊被傳遞到宿主機上,剖析器動態顯示覆蓋率的增長情況,並將這些資訊記錄在一個檔案中。
⑤應用程式執行完畢後,啟動Logiscope的事後分析工具,將覆蓋資訊記錄檔案與插裝資訊檔(在原始碼插裝在產生的附屬檔案)進行比較,協助測試人員清晰地瞭解每個被測函數內部的路徑覆蓋情況,藉此可為測試案例的改進提供協助。
⑥測試人員修改測試案例,並重新進行整個測試過程;各項測試的結果可以疊加,覆蓋率將得到增長。
經過2個多月的時間,我們對DeltaCORE 1.1版本79個檔案共計115個函數進行了覆蓋測試,覆蓋率已經達到了70.55%。編寫測試案例89個,主要的60個API函數均已獲得較高的覆蓋,覆蓋率達100%的約佔51.3%。
6 小結
我們藉助Logiscope工具對嵌入式即時作業系統DeltaCORE進行了覆蓋測試,達到了較好的覆蓋率;發現並處理了一些缺陷,提高了軟體的品質和可靠性,但同時也存在不足之處:
①測試應好好規劃,包括測試順序的選擇、測試案例的設計、測試文檔的管理等等。
②由於該測試手段依賴於作業系統的有關機制,而被測對象又是作業系統本身,因此與這些機制有關的部分代碼未被插裝和測試,否則就會出錯。比如,作業系統的初始化函數os_init,在這個函數運行完畢之前,作業系統的相應機制尚未建立起來,因此對它進行插裝就會造成問題,不能正確地得到覆蓋資訊。又比如,出於效率方面的考慮,與系統時鐘相關的部分函數未被插裝,因為在程式運行過程中,時鐘是最頻繁產生的一種外來事件,如果插裝,就會產生大量的覆蓋資訊,會對資訊緩衝、傳遞、收集和處理造成壓力。另外,所用的工具不支援對彙編函數的插裝和測試。綜合上述各種原因,DeltaCORE 1.1的總體覆蓋率還顯得比較低,需要採用其它的方法來提高它。對於非作業系統組件及應用的測試,由於不存在作業系統本身的問題,因此可望達到較高的覆蓋率。
③該方法不能用於時間效能測試。因此它屬於純軟體的測試方式,大量資料資訊的產生、傳遞與收集對被測程式的幹擾大,只能做白盒性的功能結構驗證。如果做效能測試,應採用某些軟硬結合方式的工具,比如CodeTEST。
對嵌入式軟體產品的測試是多方面的,除覆蓋測試外,還有時間效能測試、記憶體使用量測試與分析等,也是我們研究的重要課題。
轉自:http://www.uml.org.cn/embeded/qiantest.htm