(成都飛機設計研究所,成都 610091)
隨著航空飛行器研制發展,航空機載軟件呈現出了數量多,代碼量大,邏輯復雜等特點。航空機載軟件的研發也采用了基于模型的系統工程方法,系統設計能力得到了較大提升;多個型號飛機并行研制增加了機載系統數量,需要同時開發、測試和維護的軟件產品數量多、軟件狀態復雜。傳統的軟件測試的模式已經難以適應當前的航空機載軟件的研發。如何提前發現問題,保障軟件質量對傳統模式下的軟件測試提出了挑戰。
近年來,隨著科學技術的迅速發展以及高新技術在新一代戰斗機中的大規模運用,航空機載系統的能力不斷提升,系統的綜合化和復雜度也越來越高[1]。航空機載軟件是實現飛機功能的重要載體,與以往三代飛機相比,新一代飛機除了軟件規模及復雜度呈指數上升以外,機載軟件的研制主要發生了以下兩大變化:
首先,系統設計模式發生了變化。基于模型的系統工程(Model-Based Systems Engineering,MBSE)方法在型號中逐步推廣及實踐。MBSE主張以模型的形式支撐系統和軟件設計,持續貫穿整個系統研制過程。MBSE的使用,軟件設計人員基于系統模型,在完成軟件需求分解、軟件架構與功能設計后,代碼可通過模型驅動的開發手段自動生成,大大提高了軟件開發的效率。
其次,多個型號并行研制,需要并行開發、測試和維護的軟件產品數量多、軟件狀態復雜。隨著機載軟件在飛機所占功能比例越來越大,重要度越來越高,軟件從原來附屬于成品設備,剝離出來作為產品來進行管理,相應的技術管理要求更為嚴格;企業在承擔型號任務上,從原有一兩型飛機研制向多型號并行研制轉變,同時承擔的有人飛機、無人飛機達到十多個,軟件產品研制呈型號多、產品多、技術狀態多的“三多”特點。
新的系統設計模式采用及軟件多項目并行的現狀,對現有以人工方式為主的機載軟件測試提出了巨大的挑戰,需要與之適配的軟件測試手段。挑戰主要包括以下兩個方面:
首先,MBSE方法的引入,帶來了測試工作的“左移”和“右移”,如圖1所示。測試左移是指測試向軟件研制的早中期移動,測試模式將向測試驅動開發(TDD)模式轉變。在軟件研制的早中期,軟件版本發布頻繁,需求變更范圍大,要求版本迭代周期為1~2周完成一個版本的軟件測試工作,對測試效率要求非常高;測試右移是指測試向軟件研制的驗收、維護階段移動。系統及軟件設計人員很重視軟件驗收測試的效果,要求測試人員對系統功能進行完整的功能覆蓋測試。針對系統、外場試飛反饋的故障,要求測試人員能夠對故障進行分析,對系統、軟件問題快速復現和定位。

圖1 測試“左移”和“右移”
其次,由于軟件多產品線并行,軟件測試工作量十分巨大。在型號進度要求相近的情況下,各個軟件需要同時開展軟件測試,按照傳統的手工執行測試的方式,存在測試人員瓶頸的問題。
近年來,DevOps理念在互聯網企業取得廣泛的推廣和應用。DevOps(Development和Operations的組合詞)可以看作開發、技術運營和質量保證三者的交集,是一種重視“軟件開發人員(Dev)”和“IT運維技術人員(Ops)”之間溝通合作的文化、運動或慣例。透過自動化“軟件交付”和“架構變更”的流程,來使得構建、測試、發布軟件能夠更加地快捷、頻繁和可靠[2]。DevOps強調團隊協作,自動化,虛擬化以及軟件開發、測試及運營活動的新工具的橋接,目標是縮短反饋周期和開發周期,幫助軟件企業通過頻繁和自動化的軟件發布來提高對需求變更的響應能力。
我們不難找到系統工程與DevOps之間的對應關系。開發(Dev)過程被描述為涉及需求分析、設計、實現以及系統集成和測試的一系列活動,而操作(Ops)過程通常與維護活動一起,主要集中在軟件的部署及使用階段。之所以沒有單獨把質量保證(QA)活動單獨出來,并不是因為不重要,而是因為質量保證活動包括評審、測試、度量等活動,貫穿于整個軟件過程的活動。
打破部門之間的“豎井”是提高團隊協作的有效途徑。大部分航空企業的軟件開發、維護保障和質量保證部門為各自獨立的部門,不同部門之間的目標是有差異的,比如,軟件開發部門目標是盡快將變更后的軟件版本部署到系統,它希望測試工作能夠迅速完成;軟件測試部門目標是排查軟件隱藏的問題,它希望測試輸入足夠充分,并且需要預留充足的時間完成軟件測試,保證測試的高覆蓋率。當相互依賴的工作被分開時,會存在大量的信息延遲或者丟失,從而延長了整個軟件研制周期。
自動化測試是持續集成思想的重要實踐。持續集成是指一種軟件工程流程,是將所有軟件設計人員對于軟件的工作副本持續集成到公用主線的一種方法[3]。通過頻繁的自動化的構建(包括編譯、發布、自動化測試)來,可以盡快地發現集成錯誤。比如,在測試驅動開發(TDD)的實踐中,通常配置自動化的單元測試和代碼運行時錯誤檢查來發現軟件缺陷。
要開展自動化測試,光靠持續集成框架和測試工具,也許在互聯網企業是可行的,但并不適用于航空企業。有兩方面原因:一是,機上軟件大多數為嵌入式軟件,難以脫離目標系統單獨運行,需要有真實目標系統。但是航空企業都為研發驅動測試模式,軟件測試部門無獨立的硬件目標系統用于軟件測試。二是,在自動化測試實踐中,硬件難以支持設置、控制,要想完全測試自動化,需要對目標系統進行定制。芬蘭奧盧大學Lucy Ellen Lwakatare在一項關于DevOps在嵌入式領域應用的研究指出,對硬件依賴性,以及缺乏在特定環境中自動、可靠和反復部署軟件新功能的技術是阻礙DevOps在嵌入式領域應用的主要最大挑戰[4]。
為突破DevOps在嵌入式領域的最大挑戰,需引入全系統仿真技術。全系統仿真技術是對真實目標系統的虛擬化,解決了對測試硬件環境依賴的問題。全系統仿真系統是一套虛擬平臺,能夠完全仿真目標系統中對應的實際硬件[5]。開發、測試人員在這套虛擬平臺上運行被測試軟件,例如固件、操作系統、中間件或應用軟件時,可以獲得在實際目標系統上運行這些軟件的效果。
商用、開源的軟件開發、測試工具是軟件測試工具鏈的執行模塊。這里所說的工具鏈是指編譯、構建、測試所使用到的開發集成環境和測試工具。通過對市場上面向嵌入式軟件的商用、開源軟件開發、測試工具(主要為國外工具)進行調研,主流的測試工具都提供了開發接口,能夠滿足與持續集成框架的二次開發集成的需要。
因此,為突破企業現有軟件測試手段和人力資源的瓶頸,基于DevOps理念,從如何有效開展嵌入式軟件自動化測試作為切入點,測試團隊提出了一種基于DevOps的航空機載軟件測試工具鏈設計方案。設計方案主要從業務、架構、技術三個方面展開闡述[6]。
在業務視角,提出了企業內敏捷、協同的軟件測試流程。目標打破企業內軟件開發、測試之間的“豎井”,通過該流程實現在開發、測試各個團隊之間的密切合作。
在架構視角,提出了軟件測試工具鏈的架構思路。
在技術視角,提出了持續集成環境、全系統仿真環境、測試工具環境的搭建方案。持續集成環境是測試流程中各個環節的鏈條。實現了軟件每日構建(Nightly Build),以及自動化測試中待構建代碼、測試用例、目標系統仿真模型庫、測試執行結果的獲取和推送的功能。全系統仿真環境是自動化測試的運行載體。實現了目標系統的模擬仿真,仿真目標系統的容器化及測試云化部署。測試工具環境是測試流程的執行單元。測試工具環境選擇松耦合方式的方式進行設計,便于測試流水線按照項目進行個性化配置。測試工具環境的集成開發考慮了先進性、繼承性、成本三方面的因素,主要有三個做法:一是充分借鑒國外軟件測試經驗,引入優秀的開源工具。發揮開源工具靈活、可配置強的特點;二是整合企業已有的軟件測試工具,使測試技術保持繼承性;三是采購具有關鍵技術的商用工具,保證測試過程的穩定和可靠。
航空機載軟件的研制階段分為F(設計方案)、C(初樣設計)、S(試樣試制)、D(設計鑒定)、P(批型)階段。軟件測試主要集中在C、S、D階段,各階段測試業務需求如下:
在C階段,軟件需求、軟件架構功能代碼已經確定,硬件目標系統仍未設計完成。應采用測試驅動開發方式,盡早考慮,有利于保證后續自動化軟件測試的開展。該階段軟件測試的主要工作參與軟件需求的討論,進行測試需求分解;根據測試需求,搭建軟件單元、配置項自動化測試框架。
在S階段,由于系統設計變更和軟件功能設計更改,軟件需求、代碼變更十分頻繁。該階段的軟件研制具有以下兩個特點:一是機載系統狀態批次增多,軟件狀態復雜,測試人員要清楚識別、區分軟件版本狀態;二是機載軟件研制S階段周期較長,軟件開發以增量迭代的方式進行,待測試軟件較上一版本變化量小,但累計發放版本多,每個版本均需要保證軟件測試質量。針對S階段的軟件研制特點,該階段軟件測試的主要工作為建立測試流水線機制,一條測試流水線對應一項軟件的測試環境配置,保證軟件版本及測試受控;根據軟件需求、設計文檔,進行測試設計,使用測試流水線驅動自動化單元、配置項測試;根據軟件變更單,進行軟件變更影響域分析工作,進行回歸測試。
在D階段,該階段軟件已通過設計鑒定,文檔、代碼狀態穩定。該階段飛機各項科研試飛工作仍在繼續,軟件仍需排故、升級及維護保障[7]。該階段軟件測試為保證與真實環境一致性,以確認測試為主,主要在系統綜合試驗臺進行;另外,全系統仿真環境配合進行補充功能驗證,可幫助問題的定位、排查。
通過對軟件研制階段測試業務需求進行分析,機載軟件測試的瓶頸在于兩個地方:一是測試與開發協同的問題。即如何建立開發測試的協作機制,保證多技術狀態、多版本軟件測試情況下保證測試狀態準確;二是測試效率的問題。即在測試人力資源相對有限的情況下,如何構建自動化測試框架,并利用自動化測試框架,提高測試效率,完成測試任務。
因此在考慮軟件測試工具鏈架構設計時,需要考慮以上的因素。結合軟件測試業務需求,工具鏈業務架構如圖2所示。

圖2 測試工具鏈業務架構
在對軟件測試業務流程分解后,得到業務、工具鏈功能、操作對象、工具集成技術的對應關系。如表1所示。

表1 業務流程與工具鏈的對應關系
工具鏈定義:多個工具結合使用時,可以支持和構建領域工程的工作流。[8]結合企業內機載軟件測試業務需求,對工具技術架構進行了規劃,工具鏈構建應當求精而不追求面面俱到,設計準則歸納為4個字:“小”、“獨”、“輕”、“松”。“小”是指粒度小,只關注某個任務的實現。在構建測試流水線時,要細分流水線的環節步驟。最好一個環節對應到一個工具;“獨”是指每個微服務是單獨的進程。減少甚至不做工具之間的集成,降低調用服務的復雜度;“輕”是指輕量級的通信機制,盡量使用HTTP接口。在不要求實時性前提下,減少中間件的使用,降低系統復雜性;“松”是指工具鏈層間、工具之間要松耦合,可獨立部署。
基于“小、獨、輕、松”的設計原則,將軟件工具鏈設計為四層:服務、調度、集群及數據管理。測試工具鏈架構如圖3所示。

圖3 航空機載軟件測試工具鏈架構
其中,服務層是將軟件測試業務流程中使用的開發和測試工具環境,封裝為服務的形式提供測試人員使用。包括代碼構建、靜態分析、代碼審查、單元測試和配置項測試工具。
調度層內建一套驅動服務層、集群層的持續集成環境。調度層負責測試任務的創建、調度、管理,并根據測試任務需要,進行測試過程數據的自動抽取和推送。調度層包括流程引擎、分布式版本控制工具和配置管理遠程倉庫。
集群層是配置項測試的交叉測試環境。利用全系統仿真技術構建目標系統的仿真系統,負責測試腳本和目標代碼的運行及結果輸出。為解決調度層所創建測試任務自動化并發執行的問題,先使用容器技術對仿真系統封裝為微服務,通過測試云部署將容器虛擬化部署。
數據管理層負責測試過程數據、測試問題的收集和展示。包括測試管理、工程管理兩部分。包括測試管理和工程管理模塊,負責提供接口將上述數據推送到企業已有的軟件測試管理平臺和工程管理平臺。該部分將不作為本文描述的重點。
接下來,本節的其他內容將重點描述調度、集群、服務之間的關系。主要包括持續集成環境、交叉測試環境、工具環境。
2.3.1 流程引擎
流程引擎是一個持續集成的框架,可以按照時間、事件方式驅動任意的Shell腳本和Windows批處理命令的執行。構建流程引擎的目標是為不同的被測軟件建立專門的自動化測試流程,并且監控軟件測試流程,便于快速發現問題,提高測試效率。
流程引擎主要包括作業構建、作業流水線、分布式構建、構建后操作4個部分的功能:第一,作業構建功能分為串行構建、并行構建兩種方式,需要根據測試任務復雜度情況及效率要求決定采用哪一種方式來進行作業構建。一個測試任務由若干個測試作業組成,要考慮過程數據監控、構建后數據采集的難易程度,合理進行測試作業劃分時顆粒度。比如,對于代碼靜態分析任務,可以創建一個測試作業來進行構建,因為代碼可以作為整體來進行分析評估,獲取分析結果;對于單元測試任務,如果只是創建一個測試作業就顯得顆粒太粗,不便于測試過程出錯的故障排查,因此需要按照軟件模塊、單元進行結構化劃分,構建為許多個測試作業;第二,構建好的測試作業是孤立的、無方向的,需要流水線將測試作業進行串聯。作業流水線功能提供了流程建模的功能,將代碼提取、代碼構建、代碼分析、測試等一系列測試任務串聯起來。通過流水線功能,可根據不同的測試要求,快速的將已有測試作業組合在一起,形成針對某個版本軟件的自動化測試流程;第三,分布式構建主要目的是為了并發構建,提高測試執行效率。將服務器定義為主節點,其他的計算機定義為從節點,分布式構建功能定義了主節點與從節點協同構建的策略。也就是主節點根據每個從節點的忙閑狀態,動態的將測試作業分配到從節點來執行,由從節點將執行結果返回;第四,構建后操作功能完成測試作業執行后所產生的數據的采集及存儲。數據的采集是通過Python爬蟲的方式實現,從結果文件中抽取數據,并進行數據整合,形成結構化的測試結果。
流程引擎與其他系統之間的交互關系如圖4所示。

圖4 流程引擎與其他系統的交聯關系
流程引擎使用分布式版本控制工具的SSH權限,配置測試作業對配置管理遠程倉庫的訪問權限;流程引擎從配置管理遠程倉庫獲取代碼、測試模型,向遠程倉庫推送測試過程數據;測試引擎通過分布式構建功能,分配測試作業到交叉測試環境進行測試執行,從交叉測試環境讀取測試結果;作業流水線執行完成后,通過構建后操作功能,推送測試結果到測試管理平臺和工程管理平臺。
前期對市場常用的流程引擎進行了調研,主流的流程引擎工具有Jenkins、Teamcity、Travis CI、Bamboo等。目前開源的流程引擎擁有廣泛的社區基礎,具有版本迭代快,功能穩定的特點,因此考慮開源工具進行流程引擎的集成開發。
2.3.2 分布式版本控制工具
由于工具鏈涉及到軟件開發人員、測試人員、工具之間的信息交互和協同,要求之間的交互是簡單而敏捷,因此考慮輕量級的配置管理解決方案,使用分布式版本控制工具作為測試過程的配置管理工具。分布式版本控制工具與集中式版本控制工具的區別是分布式版本控制系統沒有中央服務器,每臺計算機都擁有一個完整的版本庫。就算服務機宕機,也可以正常進行版本的變更和提交,不會影響當前的開發、測試工作。
以往企業內測試團隊要同時解決測試用例版本之間、測試用例與代碼版本,測試用例版本與環境配置之間對應的難題,這往往是十分繁瑣且工作量巨大!分布式版本控制對測試團隊非常有效,采用分支機制、集成管理者工作流和配置管理遠程倉庫,使得人、工具之間的協作變得高效。
目前世界上最主流的分布式配置管理工具是Git,具有速度快,設計簡潔,完全分布式設計的特點。因此考慮使用Git作為測試團隊的版本控制工具。
2.3.3 配置管理遠程倉庫
配置管理遠程倉庫是代碼、測試用例、測試模型及文檔配置管理服務器軟件。遠程倉庫在工具鏈中具有兩個作用:1)測試版本控制協同。測試人員通過分布式版本控制工具,將測試數據提交到遠程倉庫,提交版本分支合并的變更請求;通過遠程倉庫獲取最新的測試數據版本,在本地進行工作;2)作為流程引擎的輸入和輸出。流程引擎通過鉤子機制,監聽遠程倉庫的版本變更情況。如果發生版本變更,自動觸發從遠程倉庫抽取數據,驅動測試作業的執行。業務流水線執行完畢后,通過構建后操作,將測試結果推送到遠程倉庫進行保存市面上的配置管理遠程倉庫軟件比較多,主流的有GitHub、GitLab,Bitbucket,Coding,這里面既有開源的自托管項目,也有商業軟件。
交叉測試環境是指嵌入式軟件在通用計算機環境(相對真實目標系統)中運行測試的環境。在本文所指的交叉測試環境,是用于支持航空機載配置項測試執行的全系統仿真系統、仿真系統部署環境(容器化環境和測試云)。
交叉測試環境在測試工具鏈的應用,是利用全系統仿真、軟件容器、云技術,在軟件配置項級開展并發式的功能測試及快速的回歸測試,加快問題定位和排查故障的效率。
2.4.1 全系統仿真系統
全系統仿真系統是一套仿真嵌入式目標系統的虛擬平臺,能夠完全仿真目標系統中的CPU、寄存器、內存、外設接口,全系統仿真系統示意圖如圖5所示。開發、測試人員在這套虛擬平臺上運行被測軟件,可以獲得在實際目標系統上運行這些軟件的效果。在全系統仿真系統進行軟件測試,與實際目標系統相比,具有以下兩個特點:1)支持檢查點分析。通過插入檢查點,全系統仿真系統把軟件運行狀態保存下來,支持運行狀態回放分析,便于軟件問題定位;2)支持訪問目標系統狀態。例如在真實硬件上,很難去跟蹤控制寄存器、狀態寄存器的內容,但通過全系統仿真系統,目標系統就像一個白盒,可以清楚看到內部的狀態,這對軟硬件問題的排查十分有幫助。[9]

圖5 全系統仿真系統示意圖
全系統仿真系統要在機載軟件測試使用,除要有CPU仿真模型外,還需要進行外圍設備仿真建模。外圍設備仿真建模主要指對目標系統外圍器件、接口的建模仿真,包含各種器件如內存、寄存器、外部定時器、FLASH等,各種標準的通信接口,如RS422、RS232、CAN、1553B、1394B以及FC總線。
由于CPU仿真模型的構建難度大,這類工具廠家數量在國內外并不多。適合航空航天選型芯片的工具主要有美國風河公司的Simics和上海創景公司的VDVP產品。其中Simics以支持Power PC芯片系列為主,VDVP主要側重DSP芯片系列。
2.4.2 仿真系統部署
使用軟件容器技術和云技術進行仿真系統部署。
軟件容器是一種應用程序的封裝技術。軟件容器在Linux操作系統上,提供了一個額外的軟件抽象層以及操作系統虛擬化的自動管理機制,為應用程序的運行提供所需資源。[10]創建一個容器,將全系統仿真系統封裝在容器中,可以實現全系統仿真系統從Windows向Linux的移植。軟件容器對計算機資源占用較少,在同等配置的服務器上,可以保證性能的情況下,運行多個容器。
云技術是指在廣域網或局域網內將硬件、軟件、網絡等系統資源統一,實現數據的計算、存儲、處理和共享的一種托管技術。把交叉測試環境看作為提供測試服務的測試資源池,軟件容器就是可共享的提供測試服務的資源。云技術負責提供軟件容器的動態創建,應用程序裝載,與流程引擎的調度機制。
基于軟件容器、云技術,提出了一種仿真系統的部署方案。仿真系統部署方案如圖6所示。

圖6 仿真系統部署方案
工具環境是將軟件測試業務流程中使用的開發和測試工具,封裝為服務的形式提供測試人員使用。工具環境包括代碼構建、靜態分析、代碼審查、單元測試和配置項測試工具。
工具環境的構建思路是整合現有的軟件測試,將現有脫機使用的測試工具往服務器進行遷移,形成企業內部測試資源池;引入優秀的開源工具,特別是在代碼級、單元級測試,往通用軟件測試思路轉變;開發、測試工具在與調度層進行集成時,要保持“獨”和“松”的原則,開發、測試工具之間不做集成開發,通過流程引擎進行調度。
根據以上工具鏈設計方案,進行航空機載軟件測試工具鏈的搭建。現已完成持續集成環境、靜態分析環境、協同代碼審查環境、單元測試自動化環境的搭建,并在某機電系統軟件的軟件測試中應用,達到了預期的效果,實現方案如圖7所示;完成了基于Linux系統嵌入式軟件的交叉測試環境的搭建工作,為后續機載軟件交叉測試環境的搭建奠定了基礎。
某機電系統軟件測試工具鏈的實現技術如表2所示。

表2 某機電系統軟件測試工具鏈實現技術

圖7 某型號機電系統軟件工具鏈實現方案
采用Jenkins、Git及GitLab方案搭建持續集成環境,界面如圖8所示。其中Jenkins作為主節點部署,GitLab作為配置管理遠程倉庫部署在從節點,測試工具部署在另外的從節點。

圖8 持續集成環境界面
測試數據版本控制采用分支機制、集成管理者工作流進行管理,也就是將工作分支分為master、develop兩條分支,測試人員使用Git克隆遠程倉庫的master分支版本到本地倉庫,在完成變更后,提交到遠程倉庫的develop分支,并在GitLab中向項目組長提出合并master分支的請求,由項目組長審核完成后將合并后的變更推送到遠程倉庫的master分支。
采用Jenkins、Git、GitLab、Tornado、TestBed、Covertiy工具集成方案配置靜態分析測試作業流水線,如圖9所示。開發人員通過Git在本地倉庫提交代碼,流程引擎會根據測試作業流水線配置,自動化完成被測軟件的自動提取、編譯構建、運行時錯誤檢查、代碼規則檢查、代碼質量度量,并自動推送測試結果給開發測試人員查看,實現對軟件的每日構建能力,如圖10所示。

圖9 靜態分析流程

圖10 推送Jenkins的運行時錯誤檢查報告
采用Git、GitLab、Upsource工具集成方案配置代碼審查協同工作環境。以往在項目中使用單機版的代碼審查、比對工具(Source Insight、Beyond Compare)進行代碼審查,這種方式存在兩個問題:一是開發、測試人員缺少協同的審查環境。代碼審查要求組織正式的評審會,以走讀代碼邏輯的方式來進行,但項目實際不允許這樣的實踐。二是代碼與問題對應關系不直觀。問題記錄單與代碼分開存放,時間長了關系不容易維護。通過代碼審查協同工作環境,開發、測試人員可以約定在一定時間周期內開展審查工作,測試人員在線質疑代碼中存在的問題,問題會自動推送給開發人員來進行解決。代碼與問題的對應關系在系統中進行維護,十分方便版本之間的問題比較、分析。
本文從軟件測試角度作為切入點,研究航空機載嵌入式軟件的結合方式,提出了一種航空機載軟件測試工具鏈設計方案,完成了工具鏈技術架構的搭建,持續集成環境與靜態分析、代碼審查、單元測試工具環境的集成開發,并在某飛機的機電系統軟件測試中進行應用,達到了提高測試效率的效果。測試人員在工具鏈的應用過程中,收集開發人員的反饋,作為測試工具鏈下一步優化的建議。
通過在企業內部開展航空機載軟件測試工具鏈設計與應用的探索,深切感覺工具鏈的實質是讓工具環境、自動化能力成為軟件研制的一部分,以技術能力解決過去用人工加流程要解決的問題。但工具鏈只是人、機、料、法、環的其中一環,代表著一種新的思考方式和文化。相信隨著國內機載軟件研制能力的持續進步,更多的理念能夠融入研制流程,提高軟件研制水平!