白鴻鈞,張明凱,李冠軍,楊清祥
(河南思維軌道交通技術(shù)研究院有限公司,鄭州 450000)
列車運行監(jiān)控裝置(LKJ)是中國鐵路用于防止列車冒進(jìn)信號、運行超速事故和輔助司機(jī)提高操縱能力的重要行車設(shè)備。LKJ 車載設(shè)備內(nèi)的嵌入式軟件是實現(xiàn)列車運行控制的靈魂,其運行結(jié)果的正確與否,直接關(guān)系到列車的運行安全。車載控制軟件邏輯正確性測試一直是LKJ 系統(tǒng)生產(chǎn)廠家的重要工作。業(yè)內(nèi)對LKJ 車載控制軟件的測試方法進(jìn)行了廣泛探索,一般采用手工測試和自動化測試兩種方式進(jìn)行測試。
手工測試難以實現(xiàn)待測軟件邏輯的全覆蓋,工作量大,花費時間長,且測試結(jié)果受限于測試工程師的專業(yè)知識。針對手工測試存在的問題,LKJ 生產(chǎn)廠家[1-3]及其他列控系統(tǒng)或設(shè)備生產(chǎn)廠家[4]對自動化測試方法進(jìn)行了探索。實踐證明,給通用的腳本語言增加LKJ 業(yè)務(wù)邏輯相關(guān)的關(guān)鍵字形成專用的腳本語言,以此專用腳本語言來定義測試用例,解釋執(zhí)行測試用例驅(qū)動硬件設(shè)備發(fā)送信號和采集LKJ 的反饋數(shù)據(jù),判斷是否符合預(yù)期,是可行的技術(shù)路線。
筆者參與研發(fā)的LKJ 自動化模擬仿真測試系統(tǒng)(Automatic Simulation and Test System,ASTS)在Python 語言基礎(chǔ)上定義了專用于LKJ測試的腳本語言,采用圖形編輯和手動錄制的方式形成了系列、規(guī)?;哪_本庫,成功運用于LKJ 功能、性能的自動化測試。
測試用例需要以某種編程語言來體現(xiàn),編程語言的選擇是系統(tǒng)成功的關(guān)鍵。在選定語言的基礎(chǔ)上,增加LKJ 業(yè)務(wù)邏輯相關(guān)的語言特征和底層支持函數(shù)庫,形成應(yīng)用于LKJ 特定測試場景的腳本語言。LKJ 相關(guān)的業(yè)務(wù)邏輯判斷在腳本語言中實現(xiàn),腳本語言調(diào)用底層支持函數(shù),底層支持函數(shù)驅(qū)動硬件,產(chǎn)生信號,獲取LKJ 反饋,判斷反饋結(jié)果是否符合預(yù)期,從而判定LKJ 軟件工作是否正常。
自動化測試的場景是:測試工程師編輯生成測試用例后發(fā)送到仿真測試平臺,仿真平臺執(zhí)行測試用例,驅(qū)動硬件設(shè)備,產(chǎn)生各種信號,獲取LKJ 反饋,比較LKJ 反饋是否符合預(yù)期,從而判斷LKJ車載控制軟件邏輯是否正確。測試中可能需要調(diào)整測試用例,考慮到測試工程師熟悉LKJ 業(yè)務(wù),但不一定具備編程能力的情形,不能要求測試工程師按照軟件開發(fā)的思路來編輯測試用例,編譯后生成執(zhí)行。測試用例依托的腳本語言必須具備動態(tài)執(zhí)行、高效率兩個特性,并且測試用例必須能夠可視化呈現(xiàn),因此,采用以下設(shè)計原則選擇腳本語言。
1)考慮到腳本的可擴(kuò)充性要求,應(yīng)采用業(yè)內(nèi)通用的腳本語言。
2)應(yīng)采用動態(tài)語言。動態(tài)語言在執(zhí)行時動態(tài)加載,不需要預(yù)先編譯。
3)語言性能應(yīng)滿足時效性要求。
通過對Python 語言特征的分析以及Python 混合編程的特點分析[5-6],確定Python 語言滿足以上要求,選用Python 作為測試用例的腳本語言。
在Python 語言的基礎(chǔ)上,增加LKJ 業(yè)務(wù)邏輯相關(guān)的關(guān)鍵字,比如設(shè)定列車運行速度、檢查線路限速數(shù)值、獲取LKJ 輸出信息等,生成了ASTS 腳本語言。新增的關(guān)鍵字解釋執(zhí)行時調(diào)用底層的C++函數(shù)庫[7-9],實現(xiàn)業(yè)務(wù)邏輯。ASTS 腳本語言對Python 的擴(kuò)充包括以下5 個方面。
1.2.1 設(shè)定LKJ測試所需的輸入信號
設(shè)定LKJ 測試所需的輸入信號,包括開關(guān)量信號和模擬量信號,為LKJ 提供外部信號條件,比如設(shè)定各路速度的速度值、各路壓力信號的管壓值、列車手柄狀態(tài)、機(jī)車信號等。另外,還定義了具備內(nèi)置業(yè)務(wù)邏輯的關(guān)鍵字,比如跟蹤速度函數(shù),可以持續(xù)跟蹤LKJ 限速的變化,自動調(diào)整輸入速度信號數(shù)值,使得速度貼近限速運行,直到滿足某個條件時退出速度跟蹤。
1.2.2 設(shè)定LKJ運行狀態(tài)
設(shè)定LKJ 運行狀態(tài),可以改變LKJ 的運行控制參數(shù)和設(shè)備自身狀態(tài),使LKJ 處于測試所需的工作狀態(tài),測試能夠啟動和持續(xù)進(jìn)行。比如校正LKJ的時間,設(shè)定司機(jī)發(fā)車參數(shù)(發(fā)車的車站號、運行線路、目的車站等),設(shè)定列車的檢修參數(shù)(計算列車速度所需的機(jī)車輪徑、速度傳感器每周脈沖數(shù)等),對LKJ 各插件單元的嵌入式軟件進(jìn)行版本更新。
1.2.3 獲取LKJ反饋信息
仿真測試系統(tǒng)能夠接入LKJ 內(nèi)部總線,偵聽總線數(shù)據(jù),獲取系統(tǒng)內(nèi)部通信數(shù)據(jù);也可以采集屏幕顯示器(DMI)視頻顯示和音頻輸出,通過圖像識別和音頻識別,獲取視頻音頻信息。腳本語言定義了相關(guān)的關(guān)鍵字,以實現(xiàn)獲取LKJ 信息反饋的功能。
DMI 圖像識別通過圖像二值化、字符串定位與剪裁、字符分割、字符識別等4 個過程識別字符點陣,采用“點陣對比”方式與標(biāo)準(zhǔn)字庫中的字符點陣進(jìn)行對比,識別出圖像中的字符。
DMI 音頻識別基于快速傅里葉變換(FFT)預(yù)先建立標(biāo)準(zhǔn)語音文件的識別特征庫,采集到某段語音后分析該語音的聲音特征,與識別特征庫中的語音特征進(jìn)行匹配,采用“最大可能性”原則,判定為哪一條標(biāo)準(zhǔn)語音。
1.2.4 測試結(jié)果判斷
以斷言Assert 的方式進(jìn)行測試結(jié)果判斷,判斷LKJ 的信息輸出和動作輸出是否符合預(yù)期。
1.2.5 測試進(jìn)度控制
定義了多種測試進(jìn)度控制關(guān)鍵字,比如以動態(tài)延時(ASTS_Delay)和測試過程掛起的方式控制腳本的執(zhí)行進(jìn)度,保證測試過程滿足業(yè)務(wù)邏輯要求,也可以使測試過程暫停和繼續(xù),實現(xiàn)“斷點續(xù)測”。
腳本文件是結(jié)構(gòu)化的,由文件頭和文件體組成。文件頭定義了文件的名稱、功能等,文件體是操作要素的序列和期望結(jié)果。
1.3.1 文件頭
文件頭是腳本描述,描述腳本的種類、編制人等。文件頭包括以下要素。
1)腳本名稱(#ASTS_Script_Name):用關(guān)鍵字說明腳本的功能,例如:特殊前行模式測試。
2)腳本種類(#ASTS_Script_Type):基本用例/測試實例/測試序列。
3)腳本ID(#ASTS_Script_ID):ID 由業(yè)務(wù)種類+ 序號組成。業(yè)務(wù)種類包括LKJ 種類(LKJ2000、LKJ-15S)、設(shè)備種類(主機(jī)、顯示器、其他設(shè)備)、測試種類(區(qū)分控制模式)和測試種類細(xì)分等。當(dāng)業(yè)務(wù)種類無法區(qū)分復(fù)雜或重復(fù)業(yè)務(wù)時,以序號做區(qū)分。
4)功能簡述(#ASTS_Script_Func):簡單說明腳本的功能。
5)當(dāng)前版本(#ASTS_Script_Version):該腳本的版本號。
6)發(fā)布日期(#ASTS_Script_ReleaseDate)。7)初創(chuàng)人(#ASTS_Script_Author)。
8)來源(#ASTS_Script_Creater):人工編制或手工測試錄制。
9)腳本運行所要求的LKJ 軟件版本(#ASTS_Script_LKJ_Version):LKJ 軟件、LKJ 控制條件版本號。
10) 腳本運行所要求的LKJ 數(shù)據(jù)版本(#ASTS_Script_LKJ_Data_Version):LKJ 數(shù)據(jù)版本號。
11)其他:包含腳本解釋所需的Package 列表等,用于腳本解釋器引入package。
以上1 ~10 項要素以Python 腳本注釋的方式存在。
1.3.2 文件體
文件體由一系列功能相關(guān)的操作要素和測試結(jié)果判斷組成。操作要素內(nèi)容包括動作名稱、動作參數(shù)等,比如 “設(shè)定速度輸出數(shù)值80 km/h”。腳本例子如下。
pdll.ASTS_SetTestProgress(1,20) //設(shè)置測試進(jìn)度
pdll.ASTS_TimeOut=5000 //設(shè)置超時值pdll.ASTS_InitTimeOut() //初始化超時計數(shù)
while(pdll.ASTS_CheckTimeOut() pdll.ASTS_SetKey(1) //發(fā)送按鍵 pdll.ASTS_Delay(100) //延時100 ms pdll.ASTS_SetAllGangya(800,600,0,500,500,500) //設(shè)置列車管壓 pdll.ASTS_SetGongKuang(1,0,1,0,1,1,1,1) //設(shè)置手柄信號 pdll.ASTS_SetJtcXinHao(2,1,3) //設(shè)置機(jī)車信號 pdll.ASTS_SetSudu(5,0,1) //設(shè)置速度 pdll.ASTS_SetFollowSudu(-1,361,-1,-1,5) //設(shè)置跟隨速度信號 while(pdll.ASTS_CheckTimeOut() if(pdll.ASTS_GetLKJFlag(1,7) == 21 or pdll.ASTS_GetLKJFlag(2,7) == 21): //采集LKJ反饋信息 pdll.ASTS_Assert(1) //保存測試結(jié)果 else: pdll.ASTS_Assert(0) 保存測試結(jié)果 pdll.ASTS_Delay(1) pdll.ASTS_Delay(1) 測試腳本可以由測試人員在文本編輯軟件中直接輸入語句來生成,也可以通過圖形拖拽方式生成。在實際測試工作中,測試人員習(xí)慣先進(jìn)行手動測試,記錄下自己的測試過程,之后將測試過程轉(zhuǎn)化為腳本,經(jīng)合并拼接后錄入到系統(tǒng)。 ASTS 將腳本功能或語句抽象為圖形控件,每個圖形控件內(nèi)置特定的業(yè)務(wù)邏輯。編輯測試腳本時,根據(jù)業(yè)務(wù)功能,選定相應(yīng)的圖形控件,按順序拖動到編輯區(qū),設(shè)定控件屬性,即可生成測試腳本。圖形化編輯可視化強,智能化程度高,大大減輕了腳本編輯的工作量。 在實際測試工作中,測試人員經(jīng)常先進(jìn)行手動測試,手動測試過程通過才能轉(zhuǎn)化為自動測試用例。手動測試過程記錄智能轉(zhuǎn)換為測試用例腳本,將會在很大程度上減少測試人員的工作量。 通過對用戶手動測試過程的分析和提煉,ASTS實現(xiàn)了自動記錄測試人員的手動測試過程,并轉(zhuǎn)化為測試腳本的軟件方法。 如圖1 所示,手工錄制腳本的過程如下。 1)記錄用戶的工作環(huán)境描述,形成文本塊T1 記錄用戶的登錄名稱和時間。通過特定的軟件通信協(xié)議讀取當(dāng)前設(shè)備的硬件版本和軟件版本。由用戶指定本次手動測試的主要目的。 2)由用戶指定需要跟蹤的LKJ 反饋項目 腳本文件中的期望結(jié)果是判斷腳本執(zhí)行是否成功的標(biāo)志,非常重要。實際測試中,LKJ 反饋輸出具有很強的時效性,如果讓用戶在測試中選擇確定輸出項目的話,可能會錯過時機(jī),從而記錄下錯誤的反饋輸出結(jié)果。手工錄制腳本前,在軟件界面中由用戶點擊選擇要跟蹤的LKJ 反饋輸出項目,比如跟蹤“緊急制動輸出狀態(tài)”。形成文本塊T3,T3 的形式如“跟蹤:緊急制動輸出狀態(tài)”。 圖1 手工錄制腳本的流程Fig.1 Manual scripts record process 3)記錄用戶的點擊操作過程 用戶點擊“開始錄制腳本”啟動手動測試,系統(tǒng)記錄用戶的手動測試過程(包括設(shè)定項目、項目數(shù)值和相對開始的時間),形成文本塊T2。比如記錄下某用戶的操作過程的文本塊T2: 設(shè)定速度,速度值=0 km/h,操作時間=0 s; 設(shè)定信號燈,綠燈,操作時間=5 s; 設(shè)計開車參數(shù),設(shè)定司機(jī)號=1234,時間=8 s; 設(shè)定速度,速度=20 km/h,操作時間=58 s; 設(shè)定速度,速度=40 km/h,操作時間=80 s; 設(shè)定信號:信號=紅燈,操作時間=103 s; 4)獲取跟蹤結(jié)果 用戶點擊“獲取跟蹤結(jié)果”,系統(tǒng)自動讀取當(dāng)前被測試系統(tǒng)的反饋結(jié)果,并與指定的輸出結(jié)果跟蹤項目進(jìn)行匹配,修訂文本塊T3。比如此時T3 內(nèi)容為“緊急制動輸出狀態(tài)=輸出”。 5)腳本規(guī)范化 對文本塊T2 進(jìn)行規(guī)范化處理,規(guī)范化處理的目的是將操作過程映射到操作元素。過程如下。 對每一步操作內(nèi)容,遍歷操作要素描述庫,查找對應(yīng)的操作要素。比如“設(shè)定速度”的要素類型為2。 根據(jù)操作要素類型,確定操作內(nèi)容是否完整,如果不完整,則補充默認(rèn)值。比如操作過程的第3步“設(shè)定開車參數(shù)”,用戶沒有設(shè)定發(fā)車車站號,則系統(tǒng)自動取默認(rèn)值。 將文本塊T1、T2、T3 進(jìn)行組合,形成腳本文件。 此時生成了完整的描述性文本文件,文件中的元素基本與腳本一一對應(yīng),可以很容易地轉(zhuǎn)換為腳本。生成的描述性文本如下所示。 文件頭:用于測試紅燈停車模式的腳本,運行于LKJ-15S 中,要求軟件版本為V1.0.1,自身版本V1.0,由張三錄制,錄制時間2018 年7 月27 日。 操作元素序列如下。 設(shè)定速度參數(shù):要素類型=2,操作時間=0 s,速度值=0 km/h; 設(shè)定信號燈:要素類型=3,操作時間=5 s,信號=綠燈; 設(shè)計開車參數(shù):要素類型=1,操作時間=8 s,設(shè)定司機(jī)號=1234,設(shè)定發(fā)車車站號=25; 設(shè)定速度:操作要素=2,操作時間=58 s,速度=20 km/h; 設(shè)定速度:操作要素=2,操作時間=80 s,速度=40 km/h; 設(shè)定信號:操作要素=3,操作時間=103 s,信號=紅燈。 期待輸出:緊急制動輸出=輸出。 ASTS 應(yīng)用于LKJ 的自動化測試,實踐表明,測試腳本的設(shè)計合理,動態(tài)解釋執(zhí)行靈活,且執(zhí)行效率高。腳本的圖形化生成方式、手工錄制生成方式大大減輕了測試工程師的工作量,學(xué)習(xí)曲線平滑,測試工程師的工作經(jīng)驗很容易地轉(zhuǎn)化為系統(tǒng)的測試用例。 進(jìn)一步,自定義的腳本語言可以根據(jù)應(yīng)用需求,方便地擴(kuò)展到其他自動化設(shè)備的測試場景,具有很大的應(yīng)用前景。2 腳本語言生成
2.1 測試腳本的圖形化編輯
2.2 手動測試錄制腳本
3 結(jié)論