杜孝平,張 祿,李 曄
DU Xiaoping,ZHANG Lu,LI Ye
北京航空航天大學 軟件學院,北京100191
College of Software,Beihang University,Beijing 100191,China
AFC(Automatic Fare Collection)系統(tǒng)又稱為自動售檢票系統(tǒng),是城市公共交通中的一項重要技術(shù)[1],為城市軌道交通帶來了諸多益處。改革開放以來,北京城市公共交通尤其是城市軌道交通基礎(chǔ)設(shè)施和運營管理得到了較快發(fā)展,AFC 作為城市軌道交通運營不可缺少的核心組成系統(tǒng),為運營的科學管理提供依據(jù)[2]。北京市AFC 系統(tǒng)在投入運營前需要進行常規(guī)連接測試、異常連接測試、功能測試、專項測試、集成測試等測試工作。異常連接測試的任務(wù)是測試AFC 系統(tǒng)中被測車站設(shè)備和系統(tǒng)對異常數(shù)據(jù)的處理是否符合《北京軌道交通AFC系統(tǒng)設(shè)計及實施規(guī)范》(簡稱“實施規(guī)范”)中的相關(guān)要求,它是檢測AFC 系統(tǒng)容錯性的重要手段。
文獻[3-5]討論了在平臺搭建基礎(chǔ)上對AFC 功能和接口進行測試的問題;文獻[6-7]在討論模擬測試工具的設(shè)計實現(xiàn)基礎(chǔ)上,介紹了對AFC 系統(tǒng)的功能與接口測試?,F(xiàn)有文獻尚未看到對異常連接測試的相關(guān)測試工具研究的介紹。
負責北京市AFC 系統(tǒng)檢測的北京市軌道交通指揮中心現(xiàn)在針對異常數(shù)據(jù)處理的測試方式是利用一個輔助測試工具,通過熟悉AFC 系統(tǒng)的人員對照實施規(guī)范中的數(shù)據(jù)結(jié)構(gòu),手動構(gòu)造測試數(shù)據(jù),并按測試用例逐步發(fā)送/接收數(shù)據(jù),人工對比接收到的數(shù)據(jù)和測試用例中的預(yù)期數(shù)據(jù)是否一致,來判斷被測對象是否滿足要求。其測試方式對人員素質(zhì)要求較高,且編制數(shù)據(jù)與控制數(shù)據(jù)收發(fā)過程效率低下,易于出錯。本文對設(shè)計實現(xiàn)一個異常連接測試工具用于完成上述測試任務(wù)進行討論。該工具可自動生成測試數(shù)據(jù),自動控制數(shù)據(jù)收發(fā)流程,降低測試人員對系統(tǒng)業(yè)務(wù)了解的要求,提高測試效率。
AFC 系統(tǒng)一般采用5 層架構(gòu)體系:清算中心(AFC Clearing Center,ACC)、線路中心(Line Center,LC)/多線路中心(Multiple Line Center,MLC)、車站計算機系統(tǒng)(Station Computer,SC)、車站終端設(shè)備(Station Level Equipment,SLE)和車票層[8-11],如圖1 所示。異常連接測試的任務(wù)是測試MLC、SC 與SLE 之間對異常數(shù)據(jù)的處理是否符合實施規(guī)范的要求。異常連接測試工具需要具備仿真上述某一層系統(tǒng)或設(shè)備同其他被測系統(tǒng)或設(shè)備(簡稱被測對象)建立連接,向被測對象發(fā)送消息并檢查應(yīng)答的功能,具體包含仿真MLC 測試SC、仿真SC 測試MLC與SLE以及仿真SLE測試SC四部分。其開發(fā)原理是基于AFC 系統(tǒng)各層次的通信接口協(xié)議,由仿真工具模擬生成各層次系統(tǒng)或設(shè)備的測試數(shù)據(jù),與被測對象進行通信,驗證測試數(shù)據(jù)能否符合實施規(guī)范的要求[12]。
圖1 AFC 系統(tǒng)層次圖
異常連接測試的一般流程為先準備測試數(shù)據(jù),再與被測對象建立連接,最后按測試用例收發(fā)數(shù)據(jù),若收發(fā)數(shù)據(jù)的順序和內(nèi)容都與測試用例一致,則該測試用例通過,否則中斷測試用例的執(zhí)行,對錯誤進行記錄。工具設(shè)計以盡力降低系統(tǒng)耦合度,實現(xiàn)數(shù)據(jù)共享,加強功能函數(shù)復(fù)用為原則。基于此原則,本工具的總體架構(gòu)設(shè)計為界面層、支撐層、數(shù)據(jù)層三層。界面層為直接面向用戶的功能層,包含測試數(shù)據(jù)準備、實現(xiàn)與被測對象的連接以及執(zhí)行測試功能;支撐層為工具的運行提供公用的功能函數(shù),為界面層的各個功能提供有效支持;數(shù)據(jù)層為整個工具的運行提供數(shù)據(jù)支撐,用于存儲自動生成的測試數(shù)據(jù)、測試日志以及測試數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)和測試用例結(jié)構(gòu)數(shù)據(jù)。測試工具的總體結(jié)構(gòu)如圖2 所示。
圖2 測試工具的總體架構(gòu)
為實現(xiàn)本工具的各功能,使其能替代大部分人工測試工作,需要解決兩個關(guān)鍵問題:測試數(shù)據(jù)的自動生成和測試用例的自動執(zhí)行,下面為這兩個問題提供解決思路。
3.2.1 自動生成測試數(shù)據(jù)
為了能夠自動生成測試數(shù)據(jù),首先需要根據(jù)測試數(shù)據(jù)的特征將其進行分類,再利用這些分類數(shù)據(jù)根據(jù)需要靈活生成滿足測試需求的測試數(shù)據(jù)。自動生成的測試數(shù)據(jù)是否正確依據(jù)實施規(guī)范規(guī)定的內(nèi)容來判斷。
實施規(guī)范中規(guī)定的測試相關(guān)數(shù)據(jù)由大量數(shù)據(jù)字段構(gòu)成?;谧詣由蓽y試數(shù)據(jù)時每個字段被處理的方式的不同,可將這些數(shù)據(jù)字段歸納為六類:
(1)固定內(nèi)容字段。包含由實施規(guī)范規(guī)定的數(shù)據(jù)起始、結(jié)束標識等字段。這類字段長度與內(nèi)容都在實施規(guī)范中有明確的定義,其值固定不變。
(2)隨本工具模擬的設(shè)備不同而變化的字段。包含設(shè)備ID、設(shè)備IP、設(shè)備群組號等設(shè)備的基本信息字段。這類字段長度固定,內(nèi)容隨設(shè)備而變。
(3)隨時間變化的字段。包含描述數(shù)據(jù)發(fā)送時間、交易生成時間等與時間相關(guān)的字段。這類字段長度不變,內(nèi)容隨時間變化,且其值來自于數(shù)據(jù)產(chǎn)生時的系統(tǒng)時間。
(4)隨測試用例變化的字段。這類字段用于描述由本工具向被測對象發(fā)送的消息錯誤應(yīng)答中的錯誤碼,其值由測試用例中規(guī)定的錯誤類型確定。這類字段長度不變,內(nèi)容隨具體測試用例而變。
(5)描述數(shù)據(jù)包長度的字段。這類字段長度不變,其值隨數(shù)據(jù)包的大小不同而不同。
(6)需要人工參與填寫數(shù)據(jù)值的字段。包含請求指定包數(shù)目、狀態(tài)數(shù)量數(shù)據(jù)等。這類字段長度不變,其值在實施規(guī)范和測試用例中都沒有規(guī)定,需要測試者按實際情況填寫,該類數(shù)據(jù)字段很少,僅在少量測試數(shù)據(jù)中出現(xiàn),對自動生成測試數(shù)據(jù)的影響不大。
自動生成測試數(shù)據(jù)時,每個測試數(shù)據(jù)由多個前述數(shù)據(jù)字段構(gòu)成,單個數(shù)據(jù)字段的長度和結(jié)構(gòu)不變,但整個測試數(shù)據(jù)的長度和結(jié)構(gòu)隨測試的不同而不同。
測試數(shù)據(jù)屬于半結(jié)構(gòu)化數(shù)據(jù),利用關(guān)系型數(shù)據(jù)庫存儲管理較為困難。可擴展標記語言(XML)是半結(jié)構(gòu)化數(shù)據(jù)的一個特例[13],XML 數(shù)據(jù)模型能很好地實現(xiàn)對半結(jié)構(gòu)化數(shù)據(jù)的管理以及不同程序或模塊對半結(jié)構(gòu)化數(shù)據(jù)的共享[14]。本文以XML 作為測試數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)和測試用例結(jié)構(gòu)數(shù)據(jù)的存儲語言。
為實現(xiàn)自動生成測試數(shù)據(jù)的功能,可將每個數(shù)據(jù)的具體結(jié)構(gòu)和固定內(nèi)容按一定規(guī)則用XML 存儲于配置文件中,通過自動生成測試數(shù)據(jù)函數(shù)(在4.2 節(jié)介紹)解析配置文件來生成測試數(shù)據(jù)。配置文件中測試數(shù)據(jù)的結(jié)構(gòu)如圖3 所示。
圖3 測試數(shù)據(jù)存儲結(jié)構(gòu)
圖中第2~4 行分別用于描述實施規(guī)范中數(shù)據(jù)的一級分類(如控制數(shù)據(jù))、子分類(如控制數(shù)據(jù)中的命令數(shù)據(jù))與數(shù)據(jù)的具體名稱(如設(shè)備運行控制命令)。
第5~10 行用于表示一個數(shù)據(jù)字段,其中第10 行中的property 屬性用于標識該字段屬于六個數(shù)據(jù)字段分類中的哪一類。
第11~20 行用于表示一個特殊的數(shù)據(jù)片段的結(jié)構(gòu),該數(shù)據(jù)片段可以在一個測試數(shù)據(jù)中重復(fù)多次。
自動生成測試數(shù)據(jù)函數(shù)在解析測試數(shù)據(jù)結(jié)構(gòu)后,根據(jù)測試數(shù)據(jù)結(jié)構(gòu)中每個數(shù)據(jù)字段的分類來做出相應(yīng)的處理,生成預(yù)期的測試數(shù)據(jù)。自動生成測試數(shù)據(jù)函數(shù)對各類字段的處理方法如下:
對于第一類字段,直接取其固定值寫入。
對于第二類字段,通過提取本工具模擬設(shè)備時填寫的設(shè)備相關(guān)信息來寫入。
對于第三類字段,取生成該字段時的系統(tǒng)時間填入數(shù)據(jù)字段。該類字段描述的是數(shù)據(jù)發(fā)送時間、交易生成時間等,屬于即時內(nèi)容。
對于第四類字段,其數(shù)據(jù)內(nèi)容需要在自動執(zhí)行測試用例時實時填入,即通過讀取測試用例中的相應(yīng)數(shù)值來填入。該類字段的值是在測試用例中規(guī)定的,同一類數(shù)據(jù)在不同的測試用例中該值都可能不同,需要在執(zhí)行測試用例時實時填入。
對于第五類字段,在數(shù)據(jù)包生成完成后通過計算數(shù)據(jù)包長度填入。其值來自于將測試數(shù)據(jù)中每個字段的字節(jié)長度相加的結(jié)果。
對于第六類字段,自動生成測試數(shù)據(jù)函數(shù)生成默認的固定值,這些默認值可能并不符合實際情況,但在大部分測試用例中并不影響測試結(jié)果,若用戶不想使用默認值,則可以自己修改該類數(shù)據(jù)字段的值。
3.2.2 自動執(zhí)行測試用例
執(zhí)行測試用例時,是由測試人員逐條執(zhí)行測試用例的每個步驟,觀察實際操作結(jié)果與測試用例的描述結(jié)果是否相同。其中每個步驟的操作內(nèi)容可以分為兩類:向被測對象發(fā)送數(shù)據(jù)和對比來自被測對象的數(shù)據(jù)與測試用例描述數(shù)據(jù)是否相同。自動執(zhí)行測試用例的功能,可以通過取出以XML 文件組織的測試用例,根據(jù)解析的結(jié)果調(diào)用相應(yīng)的功能函數(shù)并獲取相應(yīng)的測試數(shù)據(jù)來實現(xiàn)[15]。測試用例按一定規(guī)則用XML 存儲在配置文件中,測試用例的每個步驟作為一個節(jié)點,每個節(jié)點中存儲數(shù)據(jù)名稱,并區(qū)分該數(shù)據(jù)是“發(fā)送”還是“接收”。在自動執(zhí)行測試用例時,自動執(zhí)行測試用例函數(shù)解析配置文件,當節(jié)點中的數(shù)據(jù)標記為“發(fā)送”時,則調(diào)用自動生成測試數(shù)據(jù)函數(shù)生成相應(yīng)測試數(shù)據(jù)或直接獲取已經(jīng)存在的測試數(shù)據(jù)并發(fā)送,然后繼續(xù)讀取下一個節(jié)點;當節(jié)點中的數(shù)據(jù)標記為“接收”時,則調(diào)用數(shù)據(jù)解析函數(shù)(在4.2節(jié)介紹)解析接收到的數(shù)據(jù),對比接收到的數(shù)據(jù)特征與節(jié)點中存儲的數(shù)據(jù)特征是否相同,若相同則繼續(xù)讀取下一個節(jié)點;若不同則中止測試用例的執(zhí)行,提示用戶測試用例執(zhí)行出錯。用例執(zhí)行過程中收發(fā)的數(shù)據(jù)和提示信息都會記錄于日志文件中。
本測試工具的界面層按用戶行為主要分為三部分:與被測對象連接、數(shù)據(jù)準備和執(zhí)行測試。
與被測對象連接部分需要實現(xiàn)配置測試工具的連接信息來與被測對象建立連接,并向被測對象發(fā)送測試數(shù)據(jù)以及接收來自被測對象的數(shù)據(jù)的功能。
數(shù)據(jù)準備部分需要實現(xiàn)自動生成測試數(shù)據(jù),解析顯示測試數(shù)據(jù)的功能。
執(zhí)行測試部分需要實現(xiàn)自動執(zhí)行測試用例,執(zhí)行過程中自動生成測試數(shù)據(jù),解析來自被測對象的數(shù)據(jù)的功能。
異常連接測試中要求傳輸?shù)臄?shù)據(jù)利用基于TCP/IP的SOCKET 協(xié)議進行傳輸。根據(jù)實際測試需求,本工具可模擬測試對象主動連接實際的被測對象(如利用本工具模擬SC 測試MLC 以及模擬SLE 測試SC 時,由本工具向被測對象MLC 和SC 發(fā)出連接請求);或作為模擬的測試對象等待實體被測對象主動連接(如利用本工具模擬MLC測試SC以及模擬SC測試SLE時,本工具被動等待來自實測對象SC 與SLE 的連接請求)。主動請求連接的一方稱為客戶端,等待連接請求的一方稱為服務(wù)端。建立連接時,由服務(wù)端監(jiān)聽某個端口,客戶端根據(jù)服務(wù)端的IP 地址和其監(jiān)聽的端口號與服務(wù)端建立連接。
與被測對象建立連接、發(fā)送接收數(shù)據(jù)通過C#的socket庫實現(xiàn)。建立連接的過程如圖4 所示。
圖4 建立連接過程
該部分由自動生成測試數(shù)據(jù)函數(shù)和數(shù)據(jù)解析函數(shù)來實現(xiàn)。為方便對自動生成測試數(shù)據(jù)函數(shù)的原理進行說明,將圖3 所示的XML 文件抽象為圖5(a)所示的樹狀結(jié)構(gòu),將實際測試數(shù)據(jù)(一個二進制文件)內(nèi)容抽象為圖5(b)所示的結(jié)構(gòu)。自動生成測試數(shù)據(jù)函數(shù)首先解析如圖3 所示的XML 文件,找出要生成的測試數(shù)據(jù)節(jié)點(如DataType_2),然后遍歷該節(jié)點下的每個子節(jié)點Row1,Row2,…,每個子節(jié)點即一個數(shù)據(jù)字段,函數(shù)判斷該數(shù)據(jù)字段屬于六個數(shù)據(jù)字段分類中的哪一類,按3.2.1小節(jié)中對相應(yīng)數(shù)據(jù)字段的處理方法生成數(shù)據(jù)內(nèi)容,并將數(shù)據(jù)內(nèi)容填入圖5(b)所示的相應(yīng)片段中。若某個Row節(jié)點下存在children 子節(jié)點(如Row2,其生成的數(shù)據(jù)內(nèi)容設(shè)為x),則需要為children 節(jié)點的子節(jié)點Row′1,Row′2,…生成數(shù)據(jù)內(nèi)容,并插入到Row2節(jié)點的數(shù)據(jù)內(nèi)容之后,且需要循環(huán)生成x遍children 節(jié)點的子節(jié)點內(nèi)容。當Row節(jié)點遍歷完成,則測試數(shù)據(jù)也生成完畢。
數(shù)據(jù)解析函數(shù)用于解析一個已經(jīng)存在的數(shù)據(jù)包,通過取二進制數(shù)據(jù)中的特定位置的字節(jié)與實施規(guī)范中的定義比對,以此判斷該數(shù)據(jù)的具體名稱,并由該具體名稱從圖3 的XML 文件中獲取相應(yīng)數(shù)據(jù)結(jié)構(gòu),然后將該數(shù)據(jù)包按該結(jié)構(gòu)分解展示給用戶查看和修改,方便用戶對數(shù)據(jù)包的理解和維護。
圖5 抽象結(jié)構(gòu)
圖6 為本工具的自動生成測試數(shù)據(jù)的界面。圖中A區(qū)域表示數(shù)據(jù)分類結(jié)構(gòu)樹,由圖3 的XML 文件生成;B區(qū)域表示自動生成的測試數(shù)據(jù)。
圖6 自動生成數(shù)據(jù)界面
該部分由自動生成測試數(shù)據(jù)函數(shù)、自動執(zhí)行測試用例函數(shù)和數(shù)據(jù)解析函數(shù)來實現(xiàn)。執(zhí)行測試時調(diào)用自動執(zhí)行測試用例函數(shù),發(fā)送數(shù)據(jù)時調(diào)用自動生成測試數(shù)據(jù)函數(shù)生成相應(yīng)數(shù)據(jù)并發(fā)送,接收數(shù)據(jù)后調(diào)用數(shù)據(jù)解析函數(shù)解析數(shù)據(jù),并對比接收到的數(shù)據(jù)特征與測試用例中存儲的數(shù)據(jù)特征是否相同。
自動執(zhí)行測試用例函數(shù)讀取存儲有測試用例結(jié)構(gòu)的XML 文件,存儲結(jié)構(gòu)如圖7 所示。
圖7 測試用例存儲結(jié)構(gòu)
圖8 測試用例自動執(zhí)行結(jié)果
當函數(shù)讀取到SendData 節(jié)點時會發(fā)送相應(yīng)的數(shù)據(jù)。SendData 節(jié)點中存儲需要發(fā)送的數(shù)據(jù)名稱,根據(jù)該名稱函數(shù)會調(diào)用自動生成測試數(shù)據(jù)函數(shù)來生成相應(yīng)的數(shù)據(jù)。filledByTester屬性用于標識該數(shù)據(jù)中是否有需要測試人員填寫的數(shù)據(jù),如果其值為true,則測試者可以選擇本地已有的存儲數(shù)據(jù)的文件作為發(fā)送數(shù)據(jù),防止每次發(fā)送相同的數(shù)據(jù)時都需要測試者自己填寫數(shù)據(jù)內(nèi)容。如果發(fā)送的數(shù)據(jù)需要構(gòu)造某些異常,則需要errorType屬性。自動執(zhí)行測試用例函數(shù)會根據(jù)errorType 屬性的不同來更改發(fā)送數(shù)據(jù)的相應(yīng)字段,以構(gòu)造相應(yīng)的異常數(shù)據(jù)。當發(fā)送的數(shù)據(jù)是消息錯誤應(yīng)答,該反饋中需要填寫錯誤類型代碼時,則填入errorCode屬性值。
測試用例自動執(zhí)行結(jié)果如圖8 所示。
本文通過分析當前北京AFC 系統(tǒng)異常連接測試過程中存在的問題,找出了影響測試效率的瓶頸。通過總結(jié)歸納測試數(shù)據(jù)和測試流程步驟,將測試數(shù)據(jù)分為六類,測試流程步驟分為兩類,并將這些特點信息存儲于XML 文件中,由異常連接測試工具自動解析處理,開發(fā)實現(xiàn)了具有自動生成測試數(shù)據(jù)、自動執(zhí)行測試用例功能的異常連接測試工具,為測試提供了一種可選的新手段。數(shù)據(jù)結(jié)構(gòu)和測試用例步驟的可定制性,以及界面的友好性將是下一步工作的重點。
[1] Ampelas A.Automatic fare collection[C]//Proceedings of Intelligent Transportation Systems,2001:1164-1166.
[2] 趙菁.試論城市軌道交通(AFC)系統(tǒng)運營數(shù)據(jù)分析與運營管理[J].城市建設(shè),2010(11):128-129.
[3] 陳偉欣,楊俊輝,肖力揚.基于Web 的城市軌道AFC 仿真測試平臺設(shè)計[C]//第十屆中國科協(xié)年會論文集(一),鄭州,2008:284-287.
[4] 黃鐘.自動售檢票通用測試平臺的構(gòu)建[J].城市軌道交通研究,2006,9(12):32-35.
[5] 徐高峻.自動售檢票系統(tǒng)模擬測試平臺的組建與應(yīng)用[C]//2010 城市軌道交通關(guān)鍵技術(shù)論壇論文集,上海,2010:503-506.
[6] 張志敏.針對AFC 系統(tǒng)的自動化測試工具研究與實現(xiàn)[D].長沙:湖南大學,2010.
[7] 葉皚.自動售檢票軟件測試方法及其工具應(yīng)用研究[D].上海:東華大學,2010.
[8] 徐煒煒,徐駿善,葉飛.自動售檢票系統(tǒng)中車站信息管理系統(tǒng)的研究與設(shè)計[J].城市軌道交通研究,2012(5):53-56.
[9] 潘穎芳.城市軌道交通AFC 系統(tǒng)體系結(jié)構(gòu)分析與研究[J].信息技術(shù),2012(2):166-168.
[10] 裴順鑫,張寧.地鐵自動售檢票系統(tǒng)的互聯(lián)標準[J].都市快軌交通,2007(5):38-41.
[11] 陳鵬輝.城市軌道交通自動售檢票系統(tǒng)的現(xiàn)狀與發(fā)展趨勢[J].城市軌道交通研究,2009(5):10-12.
[12] 蔡佳妮.自動售檢票系統(tǒng)檢測中心檢測理念與實施策略[J].城市軌道交通研究,2011(1):24-28.
[13] 鄔晶亮.基于XML 的半結(jié)構(gòu)化數(shù)據(jù)存儲和查詢的研究與實現(xiàn)[D].上海:上海交通大學,2006.
[14] Bertolino A,Gao J,Marchetti E,et al.Automatic test data generation for XML schema-based partition testing[C]//Proceedings of the 2nd International Workshop on Automation of Software Test.[S.l.]:IEEE Computer Society,2007.
[15] 朱菊,王志堅,楊雪.基于數(shù)據(jù)驅(qū)動的軟件自動化測試框架[J].計算機技術(shù)與發(fā)展,2006(5):68-70.