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