陳 佐,張懷相,方景龍
(杭州電子科技大學(xué) 計算機學(xué)院,浙江 杭州 310018)
在軟件測試的過程中,存在著許多重復(fù)的、非創(chuàng)造性的工作,在這樣的背景下,自動化測試系統(tǒng)(automated testing system,ATS)[1]以其節(jié)省人工、縮短測試時間、提高測試效率以及增強測試穩(wěn)定性等優(yōu)點在軟件測試方面越來越受到人們的關(guān)注。
本文對嵌入式軟件自動化測試技術(shù)進行相關(guān)的研究,設(shè)計了一個高性能的嵌入式測試系統(tǒng),它提供了一個受控制的、確定的虛擬環(huán)境模擬平臺,軟件測試人員能夠在這個平臺上進行軟件的自動化測試、軟件結(jié)構(gòu)體系驗證及軟件功能可靠性驗證等各種技術(shù)指標檢驗,提高了嵌入式系統(tǒng)的測試效率,優(yōu)化了嵌入式軟件的設(shè)計,降低系統(tǒng)設(shè)計成本。
主要貢獻可總結(jié)如下:①定義了一系列測試調(diào)度原則,優(yōu)化分布式資源調(diào)度;②設(shè)計了一個自動化執(zhí)行引擎,對測試用例進行高效率的測試執(zhí)行;③構(gòu)建了一個受控制的,確定性的虛擬仿真環(huán)境,以支持嵌入式軟件運行環(huán)境;④以典型的無人機嵌入式軟件為實例,驗證嵌入式軟件自動化執(zhí)行框架的實用性、可靠性以及高效性。
本文提出一種基于虛擬仿真環(huán)境的嵌入式軟件自動化測試模型(embedded software automatic test model,EATM),它集成了數(shù)據(jù)驅(qū)動測試架構(gòu)、測試庫架構(gòu)以及分布式測試架構(gòu)等的優(yōu)點,以虛擬仿真技術(shù)構(gòu)建測試環(huán)境,以用例庫的形式統(tǒng)一管理測試用例,以測試用例作為數(shù)據(jù)驅(qū)動測試程序,并以分布式架構(gòu)管理用例調(diào)度與數(shù)據(jù)分發(fā)。
EATM框架如圖1所示,屬于典型的分布式測試架構(gòu),具體可以分為兩大組成部分:
(1)測試終端
測試終端模擬了軟件需要運行的基本嵌入式硬件環(huán)境,將其作為整個自動化測試執(zhí)行框架的環(huán)境基礎(chǔ)。在如圖1所示的QEMU半虛擬仿真環(huán)境基礎(chǔ)上,可以將測試終端細化為兩部分,一是被測軟件部分,二是測試控制部分,兩者之間以共享內(nèi)存區(qū)域作為數(shù)據(jù)交互,從而達到測試的實時性以及穩(wěn)定性。
(2)測試控制中心
測試控制中心是EATM框架的核心控制部分,主要對測試用例庫進行管理;對測試用例進行篩選以及分布式任務(wù)調(diào)度;對測試結(jié)果進行檢驗并統(tǒng)計等。測試控制中心采用基于Java Swing框架技術(shù)開發(fā),具有較強的可移植性。

圖1 嵌入式軟件自動化測試模型框架
測試終端和測試控制中心之間采用網(wǎng)絡(luò)通信方式,主要采用可靠的TCP/Socket通信形式,建立端到端的連接,用于測試數(shù)據(jù)的發(fā)送以及測試結(jié)果報告的反饋。
該框架結(jié)構(gòu)的優(yōu)點是能充分發(fā)揮分布式架構(gòu)的處理能力,具體表現(xiàn)在以下兩點:
(1)測試終端輕負載
在測試控制中心對測試用例進行篩選,對高性能的測試終端分配重要度高、較復(fù)雜的測試用例,并且采用多測試終端來減少單個測試終端的測試負荷,極大程度地提高測試的效率。
(2)測試用例協(xié)同處理
對高負載的測試用例可以拆分成多個子任務(wù),并采用一定的調(diào)度規(guī)則調(diào)度協(xié)同多個測試終端處理,可以減少單個測試終端的負荷,在很大程度上增加了并行處理測試數(shù)據(jù)的能力。
整個EATM框架主要分為4個部分:測試用例分發(fā)引擎、測試用例封裝引擎、測試用例執(zhí)行引擎以及虛擬仿真引擎。
如圖2所示,測試用例分發(fā)引擎主要以測試用例為數(shù)據(jù)流,從本地測試用例庫中按照分發(fā)調(diào)度規(guī)則進行篩選以及分發(fā);測試用例封裝引擎主要將網(wǎng)絡(luò)傳輸?shù)臏y試用例進行實例化操作,并將實例結(jié)果存儲在本地測試用例庫;測試用例執(zhí)行引擎主要以測試實例為數(shù)據(jù)來驅(qū)動整個自動化測試執(zhí)行器,以完成對測試用例的測試執(zhí)行并最終生成測試報告;虛擬仿真引擎主要搭建了整個自動化測試執(zhí)行的必要軟件環(huán)境。

圖2 EATM框架
用例分發(fā)引擎可以抽象的概括為“分發(fā)-收集”的過程,即將大量的測試數(shù)據(jù)按照一定調(diào)度原則分解成多個子任務(wù),每個子任務(wù)分配給各個終端節(jié)點,最后收集每個測試終端執(zhí)行后的測試結(jié)果。對于每個子任務(wù),可以由一個或者多個終端節(jié)點分工完成,即采用“功能分布”原則。對于給定任務(wù)的調(diào)度分配,描述了分布式測試環(huán)境中的行為信息,提供了描述分布式測試中的測試節(jié)點運行調(diào)度功能,比如不同的測試節(jié)點啟動的先后順序以及它們之間的同步關(guān)系,使框架具有擴展能力。
2.1.1 分發(fā)數(shù)據(jù)格式
可擴展標記語言(XML)[2]作為當前處理結(jié)構(gòu)化信息的主流工具,具有高擴展性、強移植性以及強可控性等突出優(yōu)點,本文基于XML設(shè)計了測試用例的結(jié)構(gòu)化格式。
一個測試用例文件由測試包、測試用例和測試結(jié)果構(gòu)成,以下給出這三者的概念:①測試包:所有測試用例的集合,根據(jù)產(chǎn)品的邏輯模塊或者測試模式(功能、性能或壓力)構(gòu)成不同的測試用例集;②測試用例:完成一個明確的測試需求所需要的執(zhí)行邏輯以及須給出的過程參數(shù);③測試結(jié)果:對一個測試用例最后的測試結(jié)果。用XML表示總體結(jié)構(gòu)如圖3所示。

圖3 測試數(shù)據(jù)XML結(jié)構(gòu)
定義1 測試數(shù)據(jù):一個測試數(shù)據(jù)格式可以表示為
TestCase=
(1)Testsuite={Testsuite|Testsuite表示某個模式下的所有測試用例集合|model表示當前測試數(shù)據(jù)使用的測試模式}
(2)Testcase={Testcase|Testcase表示測試用例集合中的一條測試用例}
(3)Process={Process|Process用來表示一條測試用例中的某個激勵}
(4)Operation={Operation|Operation表示激勵名稱}
(5)Input={Input|Input表示激勵參數(shù)名稱以及具體數(shù)值}
2.1.2 分發(fā)調(diào)度原則
在本文中的系統(tǒng)實時分發(fā)調(diào)度[3]采用靜態(tài)的、不可搶占的分布式調(diào)度原則。在EATM框架中,每個測試終端節(jié)點都是異構(gòu)的,同一時刻每個節(jié)點的性能是不同的。因此根據(jù)各節(jié)點的性能情況給各個測試終端分配不同數(shù)量以及不同“優(yōu)先級”的任務(wù),使得分布式中各節(jié)點負載基本均衡的同時達到效率最優(yōu)。分發(fā)調(diào)度流程如圖4所示。
圖4中的“測試用例篩選引擎①”,根據(jù)測試用例類型和賭輪盤算法[4]將測試用例全集劃分成多批次初級測試用例。

圖4 分發(fā)調(diào)度流程
輸入:軟件系統(tǒng)的測試用例全集T
輸出:初級測試用例t的集合FTestCaseList
(1)通過數(shù)據(jù)庫連接池獲取構(gòu)建的測試用例數(shù)據(jù)庫,取出測試用例全集T,并將每一條數(shù)據(jù)存儲在AllTestCaseList集合中,遍歷AllTestCaseList;
(2)構(gòu)建List集合tf,tp,tt分別代表3種類型的分類子集;
(3)獲對取第i個測試用例數(shù)據(jù),通過測試數(shù)據(jù)的Testsuite屬性來決定應(yīng)該被劃分到哪一個分類子集中;
(4)遍歷完成所有測試用例后,對應(yīng)的分類子集t全部構(gòu)造完成,對應(yīng)的分類子集規(guī)模大小為nf,np,nt;
(5)構(gòu)建測試用例集合List,從tf,tp,tt這3個分類子集中根據(jù)賭輪盤算法選擇一測試用例tk,將tk從原分類子集中移除并加入List,直到List的規(guī)模為(nf+np+nt)/3。
(6)構(gòu)建FTestCaseList集合,并將List加入,遞歸第(5)步直到分類子集均為空。
圖4中的“測試用例篩選引擎②”,根據(jù)測試用例的完整性以及復(fù)雜性評價測試用例,并對初始測試用例按優(yōu)先級篩選,形成最終的“任務(wù)”。


定義4 測試用例優(yōu)先級:測試用例優(yōu)先級是根據(jù)測試用例需求的完整性以及復(fù)雜性為標準進行量化,根據(jù)以上給出測試用例描述的兩個因素,可以量化的表示第i個測試用例的優(yōu)先級值為
輸入:初級測試用例t的集合FTestCaseList
輸出:初級測試用例t對應(yīng)的任務(wù)子集合task
(1)讀取初級用例t的集合FTestCaseList,依次遍歷;
(2)獲取第i個初級測試用例集ti,對集合中每條測試用例Ti進行優(yōu)先級評價記為Vi,并以此為關(guān)鍵字,以將測試用例Ti為值存儲在PriorityMap中;
(3)當對初級測試用例均進行完優(yōu)先級評價后,Prio-rityMap進行降序排序。
(4)按照優(yōu)先級越高越優(yōu)先挑選的原則,對初級測試用例t進行任務(wù)子集合的篩選,形成任務(wù)子集合task。
測試用例通過分發(fā)引擎處理,以“任務(wù)”的形式被分發(fā)到各個分布式終端。在各個測試終端,框架將所有收到的“任務(wù)”存儲在用例庫中,并對其進行封裝操作,將其實例化后的測試用例實體保存在終端的本地測試用例庫中,以作為用例執(zhí)行引擎的輸入數(shù)據(jù)。
測試用例封裝具體過程如下:
輸入:測試用例的XML文件集合TCList
輸出:測試用例實例集合TestCaseList
(1)讀取系統(tǒng)構(gòu)建測試用例的XML文件集合TCList
(2)獲取第i個測試用例,創(chuàng)建TestCase對象并設(shè)置用例ID屬性為i;
(3)創(chuàng)建Process對象,根據(jù)測試用例的XML數(shù)據(jù)格式對第i個測試用例中Process相關(guān)屬性對象信息進行解析并封裝到Process對象,最后將Process對象放入ProcessList
(4)重復(fù)(3)直到第i個測試用例中所有Process相關(guān)屬性對象信息都被解析完成;
(5)將當前的ProcessList
(6)獲取第i個測試用例的ExeStatus屬性,并賦值給TestCase的ExeStatus屬性;
(7)對TestCase進行實體驗證,若屬于完整測試用例,則存儲到TestCaseList
(8)遍歷完成集合TCList中所有測試用例后,將得到所有封裝后的測試用例實體都保存到TestCaseList之中,若該集合不為空則返回,否則拋出文件處理異常。
在整個EATM框架中,以實例化后的測試用例庫作為數(shù)據(jù)源,以插樁[5]處理方式對數(shù)據(jù)進行重定向,以任務(wù)調(diào)度機制來驅(qū)動測試終端平臺上的嵌入式程序執(zhí)行。
在整個測試過程中,測試用例執(zhí)行引擎對任務(wù)的劃分已經(jīng)確定測試實體類的調(diào)度方式,即以上層模型對下層進行輪詢檢測的模式來有序地調(diào)度各個模型用例。對測試用例執(zhí)行引擎通過插樁操作,不僅能夠動態(tài)的重定向測試數(shù)據(jù),而且能夠?qū)崟r地記錄測試過程中的執(zhí)行情況,起到了對測試進行動態(tài)跟蹤作用,提高了測試過程的自動化測試水平。
整個測試執(zhí)行引擎的執(zhí)行流程如圖5所示,其中圖5(b)是圖5(a)中測試用例執(zhí)行子流程的擴展描述,整體測試用例執(zhí)行具體過程如下:
輸入:測試用例實例集合TestCaseList
輸出:測試用例執(zhí)行結(jié)果集合TestCaseResultList
(1)啟動;
(2)初始化程序環(huán)境;
(3)任務(wù)調(diào)度隊列初始化,其功能是不斷觸發(fā)測試用例的執(zhí)行,每次觸發(fā)相當于執(zhí)行一條測試用例,即一條完整的程序執(zhí)行路徑;
(4)判斷測試用例緩沖區(qū)中是否還有測試用例未執(zhí)行,否則轉(zhuǎn)到(16);
(5)通過用例ID來從TestCaseList中獲取用例,并將該用例設(shè)置為此次循環(huán)的當前測試用例;
(6)測試用例執(zhí)行子流程執(zhí)行開始,調(diào)用首激勵;
(7)判斷激勵鏈表中是否還有未執(zhí)行的激勵,否則跳轉(zhuǎn)到(14);
(8)激勵是否有參數(shù),否則跳轉(zhuǎn)到(10);
(9)激勵參數(shù)重定向,即從當前測試用例鏈表中獲取當前激勵的參數(shù)數(shù)值;
(10)激勵執(zhí)行起始插樁記錄;
(11)激勵調(diào)用執(zhí)行;
(12)該激勵是否調(diào)用其它激勵,是則跳轉(zhuǎn)到(8);
(13)激勵結(jié)束插樁以及當前激勵狀態(tài)回寫,跳轉(zhuǎn)到(7);
(14)測試用例執(zhí)行子流程執(zhí)行結(jié)束;
(15)測試用例ID自增,跳轉(zhuǎn)到(4);
(16)結(jié)束。

圖5 測試用例執(zhí)行流程
嵌入式軟件被定義為嵌入在硬件中的操作系統(tǒng)和開發(fā)工具軟件,其中硬件平臺具有多樣性是嵌入式系統(tǒng)的主要特點。對于嵌入式軟件需要特定的硬件平臺是阻礙開發(fā)與測試的主要因素,而仿真軟件則通過軟件模擬形成一個具有基本完整硬件系統(tǒng)功能的、相對封閉的隔離環(huán)境,并且能夠保證在半虛擬化[6]環(huán)境下計算的安全性,該特性能夠有效地彌補嵌入式軟件開發(fā)測試中受平臺限制的弊端。
目前主要的指令級仿真軟件有以下幾款:QEMU[7]、國內(nèi)清華大學(xué)研發(fā)的Skyeye以及Realboard仿真軟件平臺[8]。本文中采用QEMU仿真軟件對運行平臺為ARM架構(gòu)嵌入式軟件進行仿真,例如UAV(unmanned aerial vehicle)無人機機載軟件,QEMU仿真軟件是目前較為先進且可開發(fā)源代碼的跨平臺仿真軟件,具有模擬適配度廣、速度快及跨平臺等特性,可以較優(yōu)秀的仿真出基ARM架構(gòu)的虛擬化環(huán)境。
對于各個模塊的仿真,如圖6所示:采用TCG(tiny code generator)動態(tài)二進制翻譯技術(shù)[9]進行指令的解析翻譯工作實現(xiàn)嵌入式軟件的CPU虛擬化;通過影子內(nèi)存[10]對嵌入式軟件內(nèi)存虛擬化;通過設(shè)備模擬對嵌入式軟件的I/O虛擬化。

圖6 QEMU嵌入式環(huán)境虛擬化結(jié)構(gòu)
由于完整UAV系統(tǒng)龐大而復(fù)雜,本文通過精簡無人機飛控系統(tǒng),選取飛控系統(tǒng)中無人機某幾個功能模塊來對本文提出的自動化測試框架進行驗證。該模塊包含以下功能以及主要描述:操作員打開open按鈕;無人機通過獲取電機狀態(tài)、電量的值、位姿信息以及飛行模式等來驗證在給定飛行條件無人機位姿調(diào)控能力。
通過UML以及狀態(tài)機的方式求解得到測試用例,將測試序列實例化求解得到的結(jié)果進行組合,生成測試用例數(shù)據(jù)庫,共產(chǎn)生了7974條測試用例,作為自動化測試框架的主要數(shù)據(jù)輸入。測試用例庫中數(shù)據(jù)通過EATM框架調(diào)度、分發(fā)和執(zhí)行后,結(jié)果數(shù)據(jù)被收集到測試控制中心,測試控制中心最終測試結(jié)果的統(tǒng)計并且可視化。
經(jīng)過測試用例所有的測試用例執(zhí)行結(jié)果見表1:99.51%的測試數(shù)據(jù)測試成功,說明絕大部分測試用例成功執(zhí)行且測試結(jié)果與測試期望相一致;失敗測試用例只占0.49%,具體的失敗情況可以再進一步地分析。對39條測試失敗的情況進行詳細地分析,如表2所示,所有失敗的用例均為測試執(zhí)行結(jié)果與期望值不相匹配所致,造成該錯誤原因是給出測試用例不能正確有效地模擬真實環(huán)境中數(shù)據(jù)所致,與EATM框架執(zhí)行無關(guān)。

表1 測試結(jié)果統(tǒng)計

表2 出錯結(jié)果統(tǒng)計
對于表1中成功的測試用例,按照需求中的描述進行更具體的結(jié)果統(tǒng)計,更加直觀地展現(xiàn)測試效果。如圖7所示,量化指標為無人機的最大飛行高度,即擁有相同電池容量的多架無人機,分別在不同的風(fēng)速級別下進行垂直爬升操作過程中,當無人機的電量被消耗到0%時無人機所處的高度。

圖7 各個風(fēng)速下最大高度柱狀圖
在測試過程中對所給的大規(guī)模測試用例,EATM框架可以有效地進行測試,并且在表2所示的出錯測試用例中不存在由于框架自身錯誤而影響測試的情況,驗證了EATM框架對嵌入式軟件的自動化測試具有較好的穩(wěn)定性。根據(jù)圖7中所指定量化指標的數(shù)據(jù)值對比,可得到在該實驗中測試結(jié)果與期望數(shù)據(jù)值基本保持一致,有效地驗證了本文提出的EATM框架對嵌入式軟件的自動化測試完全切實可行,具備較高的實用性。
本文提出了一種嵌入式軟件的自動化測試方法,通過半虛擬化技術(shù)仿真嵌入式軟件運行環(huán)境,構(gòu)造分布式調(diào)度算法,并且設(shè)計相應(yīng)的自動化執(zhí)行引擎,對大量的測試用例進行測試,提升嵌入式軟件測試的高效性。最后以簡化開源無人機飛控系統(tǒng)的一個單元模塊為實例,以通過模型產(chǎn)生的測試用例為數(shù)據(jù),應(yīng)用本文提出的自動化測試框架進行驗證。實驗結(jié)果表明,本框架執(zhí)行方式正確,驗證方法有效。該結(jié)果有助于對嵌入式軟件系統(tǒng)進行自動化測試和分析。今后本人將對進一步提高系統(tǒng)的執(zhí)行能力、優(yōu)化測試用例調(diào)度、完善測試結(jié)果測評等方面開展研究。