周漢清 劉 暢
(中航工業(yè)綜合技術(shù)研究所,北京 100028)
航空裝備對嵌入式軟件的質(zhì)量要求不斷提高,各種自動化嵌入式軟件仿真測試環(huán)境不斷涌現(xiàn)。目前,這些測試環(huán)境被廣泛采用,成為國內(nèi)外公認(rèn)的有效的軟件測試手段,對于發(fā)現(xiàn)軟件缺陷及提高軟件質(zhì)量起到非常關(guān)鍵的作用。由于測試腳本能夠描述復(fù)雜的測試場景使得測試更加充分,進而提高測試質(zhì)量,在仿真測試環(huán)境中,利用測試腳本來描述測試用例的輸入,并通過仿真測試環(huán)境中的腳本解釋器來執(zhí)行測試用例是一種有效的測試方法。但機載嵌入式軟件硬實時性的特點對測試腳本提出實時性的要求,為了獲得準(zhǔn)確的測試結(jié)果,在實際測試過程中,需要精確地在某一時刻注入測試激勵,并在特定的時刻觀察被測系統(tǒng)的響應(yīng)判斷執(zhí)行結(jié)果是否正確。測試激勵和結(jié)果查看通常都需要精確地在某一時刻進行,否則無法獲得準(zhǔn)確的測試結(jié)果。在構(gòu)造嵌入式軟件仿真測試環(huán)境時,實現(xiàn)激勵數(shù)據(jù)的實時控制和測試結(jié)果數(shù)據(jù)的實時收集成為業(yè)界的一大難題。為此,本文提出并實現(xiàn)了一種實時腳本技術(shù),實現(xiàn)了測試過程中激勵數(shù)據(jù)的實時控制和結(jié)果數(shù)據(jù)的實時收集,以滿足機載嵌入式軟件實時性的測試要求。
本文中,實時腳本是基于嵌入式軟件可靠性仿真測試環(huán)境SATE(Software Automation Testing Environment)實現(xiàn)的。SATE為嵌入式軟件可靠性測試提供了一個從測試用例編輯、仿真模型開發(fā)、接口配置集成,到測試用例激勵、測試數(shù)據(jù)收集、仿真模型和測試腳本的運行管理、接口驅(qū)動管理,再到測試數(shù)據(jù)管理分析的全過程解決方案。能夠滿足嵌入式軟件對嵌入特性、接口特性、實時特性以及交聯(lián)特性的要求。
測試環(huán)境采用了目前國內(nèi)外較成熟產(chǎn)品GESTE[1]、ADS2[2]等的體系結(jié)構(gòu)。如圖1所示。測試環(huán)境分為測試主控機和實時處理機兩部分,其中測試主控機主要完成測試用例、仿真模型、腳本的編輯和加載,測試過程的控制,以及測試結(jié)果的顯示與分析等。實時處理機通過真實總線與被測系統(tǒng)連接,實現(xiàn)對被測系統(tǒng)的系統(tǒng)交聯(lián)模型的仿真。執(zhí)行時實時處理機接收主控機下傳的測試數(shù)據(jù)并進行加工,完成向被測系統(tǒng)施加測試激勵的功能。此外,實時處理機還要完成測試結(jié)果數(shù)據(jù)的收集任務(wù)。
圖1 SATE軟件體系結(jié)構(gòu)
接下來,我們討論實時腳本在SATE中所處的位置以及實時腳本與SATE其他模塊之間的關(guān)系。從圖1中可以看出,測試主控機上的腳本編輯器和實時處理機上的腳本解釋器協(xié)同實現(xiàn)了SATE的實時腳本功能。測試人員通過測試主控機的腳本編輯器編寫腳本并進行語法檢查。測試開始后,測試腳本通過TCP/IP下發(fā)到實時處理機。實時處理機中的腳本解釋器在任務(wù)調(diào)度模塊的驅(qū)動下對腳本進行解釋,并將解釋完的測試激勵數(shù)據(jù)通過接口驅(qū)動管理模塊下發(fā)到被測系統(tǒng),同時解釋器接收被測系統(tǒng)的反饋結(jié)果,并根據(jù)結(jié)果執(zhí)行相應(yīng)的腳本邏輯。
由于實時處理機中的腳本解釋器是經(jīng)過深度定制的,是腳本的實際執(zhí)行機構(gòu)。主控機中的腳本編輯器中的語法檢查規(guī)則需要根據(jù)實時處理機中的腳本解釋器確定。因此,本文首先闡述實時處理機中腳本解釋器的實現(xiàn)方案。
實時處理機中腳本解釋器構(gòu)造主要包括腳本解釋器移植、解釋器裁剪、解釋器的擴展和嵌入3個主要過程。
2.1.1 腳本解釋器移植
在SATE中,實時處理機是一臺加載VxWorks實時操作系統(tǒng)的工控機,而目前Python腳本解釋器無法直接在VxWorks中進行,這就需要進行腳本解釋器移植。目標(biāo)是獲得一個能夠在VxWorks系統(tǒng)上運行的Python解釋器。
在SATE中,我們將Linux系統(tǒng)版本的Python解釋器移植到VxWorks 5.5系統(tǒng)中。具體的移植方法參見[3]。由于Python解釋器采用C語言實現(xiàn)。移植主要工作是系統(tǒng)函數(shù)替換,將Python解釋器中相關(guān)的Linux系統(tǒng)調(diào)用函數(shù)替換成VxWorks中的系統(tǒng)調(diào)用函數(shù)。
2.1.2 腳本解釋器裁剪
進行腳本解釋器裁剪的原因主要有以下兩方面,一是在上述移植的過程中,解釋器中有些系統(tǒng)調(diào)用在VxWorks中并不存在,無法進行相應(yīng)的名稱替換。對于這類系統(tǒng)調(diào)用,在移植的過程中進行裁剪刪除。第二個原因是,我們移植的目標(biāo)系統(tǒng)是一個嵌入式系統(tǒng),系統(tǒng)資源十分稀缺。由于Python腳本解釋器結(jié)構(gòu)復(fù)雜、功能龐大,使用時所占用大量的系統(tǒng)資源,因而在移植過程中,對于執(zhí)行測試腳本無關(guān)的模塊,例如網(wǎng)絡(luò)模塊、圖形用戶編程模塊、Web模塊、數(shù)據(jù)庫模塊等也進行裁剪刪除。裁剪后的腳本解釋器既滿足了執(zhí)行測試腳本的要求,同時結(jié)構(gòu)簡單緊湊、占用更少系統(tǒng)資源,具有很高的運行效率。
2.1.3 腳本解釋器擴展和嵌入
經(jīng)過上述兩步,我們獲得了一個運行在VxWorks上的Python腳本解釋器。但是為了能夠執(zhí)行測試主控機中的測試腳本,還需要這個解釋器跟實時處理機中的其他模塊相互協(xié)作。腳本解釋器擴展和嵌入就是建立協(xié)作的過程。
由于實時處理機中其他模塊都采用C語言實現(xiàn),所以擴展和嵌入就是集成C語言和Python語言。擴展是指用C語言實現(xiàn)Python的擴展模塊,然后從Python中調(diào)用這些模塊的功能。嵌入是指將Python解釋器嵌入到C語言編寫的應(yīng)用程序中,使應(yīng)用程序可以解釋執(zhí)行Python語言編寫的測試腳本。擴展和嵌入都是通過Python的C語言應(yīng)用程序編程接口來進行,由此形成的結(jié)構(gòu)如圖2所示。
圖2 Python擴展和嵌入結(jié)構(gòu)
由于嵌入實現(xiàn)比較簡單,下面主要介紹擴展的實現(xiàn)方式,擴展主要是在Python腳本解釋器的基礎(chǔ)上加入針對實時嵌入式軟件測試特性的描述,包括測試激勵、測試反饋和任務(wù)調(diào)度。
1)測試激勵
在SATE中,被測系統(tǒng)只與接口驅(qū)動管理模塊進行數(shù)據(jù)交互,實時腳本對被測系統(tǒng)的測試激勵通過接口驅(qū)動管理模塊進行施加。本文采用的擴展方式對SATE中的接口驅(qū)動管理模塊函數(shù)進行封裝,測試腳本可以通過擴展模塊提供的方法來設(shè)置激勵數(shù)據(jù)的值。最終通過接口驅(qū)動管理模塊發(fā)送給被測系統(tǒng)。實現(xiàn)后的代碼示例如下:
2)測試反饋
實時腳本獲取被測系統(tǒng)的反饋數(shù)據(jù)也是通過接口驅(qū)動管理模塊完成,接口驅(qū)動管理模塊按照接口協(xié)議接收并保存被測系統(tǒng)的反饋數(shù)據(jù)。測試腳本通過擴展的方法來獲取相應(yīng)反饋數(shù)據(jù)的值。實現(xiàn)后的代碼示例如下:
3)任務(wù)調(diào)度
測試腳本承載的測試行為被封裝成一個個獨立的測試任務(wù),測試任務(wù)分為兩種,一種是周期型任務(wù),另一種是事件型任務(wù)。周期型任務(wù)是在測試執(zhí)行過程中按規(guī)定周期重復(fù)運行。事件型任務(wù)是在指定時間到達時執(zhí)行一次。無論周期型任務(wù)和事件型任務(wù),都需要接收任務(wù)調(diào)度模塊的統(tǒng)一調(diào)度,這就需要實現(xiàn)一個擴展的注冊函數(shù),將腳本任務(wù)注冊到任務(wù)調(diào)度模塊中。注冊函數(shù)主要將任務(wù)的類型、執(zhí)行時間以及周期等信息注冊到任務(wù)調(diào)度模塊的任務(wù)列表。測試開始后,任務(wù)調(diào)度模塊根據(jù)任務(wù)的時間特性自動調(diào)用測試腳本函數(shù)。實現(xiàn)后的代碼示例如下:
腳本編輯器提供了友好的人機界面進行腳本開發(fā)。包含了常規(guī)代碼編輯器中的腳本編輯、腳本自動補全、代碼折疊、語法高亮、代碼注釋、字體放大縮小、換膚,顯示代碼行號等功能。由于Python語言是解釋執(zhí)行,在執(zhí)行過程中如果遇到語法錯誤,解釋器能夠自動停止程序運行并給出錯誤提示,因而現(xiàn)有的商業(yè)Python腳本編輯器中不包含語法檢查功能。但在SATE中,腳本的編輯和執(zhí)行分布在兩個不同的平臺。腳本解釋器執(zhí)行腳本時,測試過程已經(jīng)開始。如果此時遇到腳本語法錯誤,測試過程將被中止,此前已經(jīng)得到的測試步驟需要在修改腳本完成后重新執(zhí)行,最終造成測試執(zhí)行效率低下。因而,在測試執(zhí)行之前對腳本進行語法檢查是十分必要的。
在腳本編輯器中單獨實現(xiàn)語法檢查器工作量非常大,需要很高的開發(fā)維護成本。為此,本文提出一種實現(xiàn)腳本語法檢查的方法,這種方法的主要思路是通過在腳本編輯器中內(nèi)嵌一個特殊的腳本解釋器,在測試過程開始前,先利用該解釋器模擬運行腳本并給出語法檢查的結(jié)果。這就使我們在測試執(zhí)行開始前就能獲得一個可以正確執(zhí)行的腳本。
圖3 語法檢查腳本解釋器與執(zhí)行腳本解釋器的關(guān)系
實現(xiàn)語法檢查工作的重點是在測試主控機上的腳本編輯器中實現(xiàn)一個語法檢查用的腳本解釋器。上文已經(jīng)介紹了實時處理機中的腳本解釋器的實現(xiàn)方案。該解釋器是測試腳本的實際運行機構(gòu),是腳本編輯器中語法檢查規(guī)則建立的依據(jù)。如圖3所示,圖中左側(cè)是實時處理機中腳本解釋器的實現(xiàn)過程,右側(cè)是測試主控機上腳本編輯器中用于語法檢查的腳本解釋器的實現(xiàn)過程。標(biāo)準(zhǔn)的腳本解釋器可以直接在測試主控機中運行,因而無需腳本移植過程。除此之外,構(gòu)造過程與實時處理機中的腳本解釋器一致。
將語法檢查用的腳本解釋器內(nèi)嵌到腳本編輯器中,實現(xiàn)了語法檢查的功能。由于解釋器的構(gòu)造方式與實時處理機中的相同,因而,兩個解釋器的支持的語法結(jié)構(gòu)、語法檢查判斷準(zhǔn)則都完全一致。最終實現(xiàn)了在測試主控機的腳本編輯器中進行語法檢查,在實時處理機中的腳本解釋器中運行腳本的目的。
最后,我們使用嵌入式軟件仿真測試環(huán)境SATE對“飛機襟縫翼伺服控制模擬系統(tǒng)軟件”進行可靠性測試,測試腳本采用Python腳本進行編寫。測試概況如表1所示。
表1 工程案例項目概況
下面介紹兩個典型的測試用例。
驗證目標(biāo):測試軟件對輸入信號確認(rèn)功能(信號保持300ms確認(rèn)有效,否則保持原狀態(tài))實現(xiàn)的正確性。
驗證方法:通過實時測試腳本,控制輸入信號持續(xù)的時間。
圖4 輸入信號消抖能力測試結(jié)果
測試結(jié)果如圖4所示。驗證結(jié)論:人工測試時無法精確到ms級,因而無法完成此項功能的測試過程,無法找出軟件缺陷。仿真環(huán)境中實時測試腳本可以精確有效模擬軟件輸入信號持續(xù)時間,發(fā)現(xiàn)了軟件存在的缺陷,從而充分驗證軟件數(shù)據(jù)處理是否滿足要求。
驗證目標(biāo):測試機翼在轉(zhuǎn)動中突遇強大的氣流壓力迫使機翼突然變向轉(zhuǎn)動時軟件的響應(yīng)是否正確。
驗證方法:通過實時測試腳本,通過腳本模擬飛機異常環(huán)境條件,施加異常測試激勵數(shù)據(jù)給被測系統(tǒng)。
測試結(jié)果如圖5所示。
圖5 極端異常條件下系統(tǒng)響應(yīng)測試結(jié)果
驗證結(jié)論:仿真環(huán)境可以準(zhǔn)確模擬飛機異常環(huán)境條件,從而充分驗證在異常條件下軟件的處理能力是否滿足要求。
本文在嵌入式軟件仿真測試環(huán)境SATE中設(shè)計并實現(xiàn)了一種實時Python腳本技術(shù),通過測試實例證明,采用實時腳本技術(shù)的SATE能夠完成各種復(fù)雜測試場景的描述,具有很強的測試描述能力。通過使用CodeTest進行性能測試,測試腳本的定時精度可達1ms,能夠充分滿足機載嵌入式軟件測試的要求。綜上所述,本文設(shè)計并實現(xiàn)的實時腳本技術(shù)具有很好的推廣應(yīng)用價值。
[1] 鐘德明,劉斌,阮鐮. 嵌入式軟件仿真測試環(huán)境軟件體系結(jié)構(gòu)研究[J]. 北京航空航天大學(xué)學(xué)報,2005,31(10):1130-1134.
[2] ADS2:Avionics development system 2 generation[EB/ OL]. www.techsat.com,2004.
[3] Raskin S.How To port Python To VxWorks[EB/ OL].https://mail.python.org/pipermail/pythonlist/1999-May/003929.html.