高冬梅,梅新奎,宿文玲,宋笑兵
(1 黑龍江財(cái)經(jīng)學(xué)院 財(cái)經(jīng)信息工程學(xué)院,哈爾濱 150080;2 哈爾濱工程大學(xué) 智能科學(xué)與工程學(xué)院,哈爾濱 150080)
目前,研究人員對(duì)接口自動(dòng)化測(cè)試工具展開了深入研究。研究主要集中在接口自動(dòng)化測(cè)試框架設(shè)計(jì)與實(shí)現(xiàn)、算法生成測(cè)試用例、模型驅(qū)動(dòng)測(cè)試等方面。對(duì)于接口自動(dòng)化測(cè)試框架設(shè)計(jì)與實(shí)現(xiàn)方面,文獻(xiàn)[1]應(yīng)用Jenkins 平臺(tái)和TestNG 技術(shù),設(shè)計(jì)并實(shí)現(xiàn)了移動(dòng)端接口測(cè)試框架;文獻(xiàn)[2]應(yīng)用HttpClient 和TestNG 技術(shù),設(shè)計(jì)與實(shí)現(xiàn)了Web 的http 接口測(cè)試框架;文獻(xiàn)[3]應(yīng)用Web 開發(fā)技術(shù),設(shè)計(jì)與實(shí)現(xiàn)了輕量級(jí)接口測(cè)試框架;文獻(xiàn)[4]應(yīng)用Python 語言分析線上日志,對(duì)流量進(jìn)行回放,設(shè)計(jì)與實(shí)現(xiàn)了服務(wù)端接口測(cè)試框架。在算法生成測(cè)試用例方面,文獻(xiàn)[5]應(yīng)用蟻群算法生成測(cè)試用例;文獻(xiàn)[6]應(yīng)用正交實(shí)驗(yàn)設(shè)計(jì)算法,生成了大批測(cè)試用例。在模型驅(qū)動(dòng)測(cè)試方面,文獻(xiàn)[7]建立接口語義模型,對(duì)接口語義進(jìn)行邏輯推理、建立規(guī)則,生成測(cè)試用例;文獻(xiàn)[8]建立UML 時(shí)序圖的元模型,生成測(cè)試代碼和用例;文獻(xiàn)[9]通過系統(tǒng)變更前后的UML 用例圖、類圖和活動(dòng)圖變化,生成回歸用例;文獻(xiàn)[10]通過狀態(tài)圖生成中間模型圖,選擇相應(yīng)覆蓋率標(biāo)準(zhǔn),覆蓋圖中路徑,生成測(cè)試用例并分析覆蓋率。
然而,目前已有的自動(dòng)化測(cè)試框架或工具仍然存在以下問題:
(1)只能對(duì)被測(cè)系統(tǒng)發(fā)布的服務(wù)或http 接口進(jìn)行測(cè)試,對(duì)不屬于服務(wù)的接口無法測(cè)試。例如,定時(shí)任務(wù)和異步消息事件。
(2)接口輸出驗(yàn)證不完整,只能對(duì)接口返回結(jié)果的部分參數(shù)做簡(jiǎn)單的斷言驗(yàn)證,被測(cè)接口的數(shù)據(jù)庫表變化、發(fā)送的異步消息事件和異常無法得到驗(yàn)證。
(3)生成的測(cè)試用例,依賴算法或模型,表達(dá)能力有限。
為此,針對(duì)質(zhì)量要求嚴(yán)格的金融分布式系統(tǒng),本文提出接口自動(dòng)化測(cè)試工具,對(duì)服務(wù)接口和不屬于服務(wù)接口實(shí)現(xiàn)測(cè)試,接口返回結(jié)果實(shí)現(xiàn)精準(zhǔn)驗(yàn)證。測(cè)試工具基于IntelliJ IDEA 插件開發(fā)和實(shí)現(xiàn),插件支持生成測(cè)試代碼、生成測(cè)試結(jié)果、生成數(shù)據(jù)庫模型、生成類模型和編寫用例,并提供圖形化界面。
測(cè)試工具體系結(jié)構(gòu)的實(shí)現(xiàn),必須從被測(cè)金融分布式系統(tǒng)開發(fā)的體系結(jié)構(gòu)入手。如圖1 所示,該系統(tǒng)提供開戶、借款、還款等金融類SOA 服務(wù);接收上游系統(tǒng)傳遞的異步消息;可進(jìn)行結(jié)息、出賬和到期扣款等系統(tǒng)定時(shí)任務(wù)處理。這些接口作為金融類系統(tǒng)重要的功能和服務(wù),都應(yīng)該從接口測(cè)試層面去保障。在原有被測(cè)接口系統(tǒng)體系結(jié)構(gòu)中引入測(cè)試工具,測(cè)試工具和被測(cè)接口隸屬于同一個(gè)系統(tǒng),系統(tǒng)以多模塊的方式組織在一起。這種組織方式有利于迭代過程中開發(fā)和測(cè)試使用同樣的配置管理方式,將其部署到實(shí)際生產(chǎn)環(huán)境中,可以對(duì)測(cè)試模塊進(jìn)行打包排除。其次,這種組織方式有利于對(duì)不屬于服務(wù)的異步消息、定時(shí)任務(wù)等進(jìn)行接口測(cè)試,對(duì)質(zhì)量要求嚴(yán)格的金融類系統(tǒng)提供全面的接口測(cè)試保障。
圖1 系統(tǒng)體系結(jié)構(gòu)Fig.1 System architecture
測(cè)試工具包括生成測(cè)試代碼、生成類模型、生成數(shù)據(jù)庫模型、生成測(cè)試結(jié)果、數(shù)據(jù)驅(qū)動(dòng)和流程模板。生成測(cè)試代碼,根據(jù)接口生成測(cè)試代碼基本結(jié)構(gòu)。生成類模型,根據(jù)接口輸入?yún)?shù)、返回結(jié)果生成類模型文件。生成數(shù)據(jù)庫模型,根據(jù)數(shù)據(jù)庫配置生成數(shù)據(jù)庫表模型。生成測(cè)試結(jié)果,根據(jù)開發(fā)接口生成的結(jié)果進(jìn)行收集和驗(yàn)證,接口生成的結(jié)果包括接口返回結(jié)果、數(shù)據(jù)庫變更、發(fā)送的消息和可能的異常,測(cè)試框架對(duì)這些結(jié)果進(jìn)行收集后和期望的結(jié)果進(jìn)行對(duì)比驗(yàn)證。數(shù)據(jù)驅(qū)動(dòng)的設(shè)計(jì)是為準(zhǔn)備調(diào)用開發(fā)模塊所需要的數(shù)據(jù),并完成開發(fā)接口的調(diào)用。流程模板的設(shè)計(jì)是為每個(gè)接口測(cè)試提供流程的模板,所有接口測(cè)試的流程都包括初始化、獲取數(shù)據(jù)驅(qū)動(dòng)、執(zhí)行測(cè)試和生成結(jié)果與驗(yàn)證。
文獻(xiàn)[6]從數(shù)據(jù)模型、服務(wù)模型和計(jì)劃模型3方面建立接口測(cè)試模型;文獻(xiàn)[7]從服務(wù)輸入、服務(wù)輸出、服務(wù)運(yùn)行參數(shù)和服務(wù)間依賴關(guān)系4 方面建立服務(wù)接口契約模型。文獻(xiàn)[8-10]從模型驅(qū)動(dòng)測(cè)試角度,建立UML 時(shí)序圖的元模型、類圖、用例圖、活動(dòng)圖和狀態(tài)圖,生成測(cè)試代碼。文獻(xiàn)[11]從測(cè)試接口、測(cè)試用例、測(cè)試套件、輸入輸出和前置條件定義測(cè)試模型及關(guān)系。
在以上文獻(xiàn)研究的基礎(chǔ)上,金融分布式系統(tǒng)接口測(cè)試模型,從基本對(duì)象模型和數(shù)據(jù)準(zhǔn)備模型兩個(gè)方面抽象。其中,基本對(duì)象模型,用于描述接口測(cè)試中包含的對(duì)象;數(shù)據(jù)準(zhǔn)備模型,用于描述數(shù)據(jù)準(zhǔn)備時(shí)需要的要素。
(1)基本對(duì)象模型定義包括:表、異步消息事件和對(duì)象。
VirtualTable =<tableName,tableBaseDesc,flags tableData >
VirtualEventObject =<eventObject,eventCode,topicId>
VirtualObject =<description,objClass,object,objBaseName,objBaseDesc,flags>
其中,tableName 為表名;tableBaseDesc 為表描述;flags 為驗(yàn)證標(biāo)識(shí)符;tableData 為表中數(shù)據(jù);eventObject 為事件對(duì)象;eventCode 為事件編碼;topicId 為事件ID;description 為對(duì)象的描述信息;objClass 為對(duì)象對(duì)應(yīng)類;object 為對(duì)象信息;objBaseName 為基類名;objBaseDesc 為基類描述。
(2)數(shù)據(jù)準(zhǔn)備模型定義包括:數(shù)據(jù)庫表、上下文參數(shù)、輸入?yún)?shù)、輸出結(jié)果、異步消息事件集合、異常和測(cè)試單元。
VirtualDataSet=<{virtualTablei}>:數(shù)據(jù)庫表集合;
VirtualParams=<{parami}>:上下文參數(shù)集合;
VirtualArgs=<{inputArgi}>:輸入?yún)?shù)集合;
VirtualResult=<result>:返回結(jié)果對(duì)象;
VirtualEventSet =<{virtualEventObjecti}>:異步事件對(duì)象集合;
VirtualException =<expectException>:期望異常對(duì)象;
TestUnit=<description>:數(shù)據(jù)庫表等6 種類描述信息的抽象。
數(shù)據(jù)驅(qū)動(dòng)是以文件的形式提供接口測(cè)試所需要的數(shù)據(jù),常見的數(shù)據(jù)交換格式有XML[12]、JSON、YAML[13]和CSV。本文選擇YAML 格式文件,避開了XML 文件中的各種引號(hào)和括號(hào)等,上手較快并且文件可讀性較高。YAML 文件由模型中定義的輸入?yún)?shù)、準(zhǔn)備的數(shù)據(jù)集、期望的數(shù)據(jù)集、期望的消息事件集、期望的輸出結(jié)果和期望的異常組成。其中,輸入?yún)?shù)負(fù)責(zé)組裝接口所需要的所有參數(shù);準(zhǔn)備數(shù)據(jù)集負(fù)責(zé)組裝接口所需要的所有數(shù)據(jù)庫數(shù)據(jù);期望數(shù)據(jù)集,負(fù)責(zé)被測(cè)接口數(shù)據(jù)庫表的變化期望值;期望消息事件集,負(fù)責(zé)被測(cè)接口異步消息事件的期望值;期望結(jié)果,負(fù)責(zé)被測(cè)接口返回結(jié)果的期望值;期望異常,負(fù)責(zé)被測(cè)接口產(chǎn)生異常的期望值。在YAML 文件中,每個(gè)測(cè)試用例都準(zhǔn)備好這6 類元組后,將每個(gè)元組的內(nèi)容轉(zhuǎn)換為數(shù)據(jù)準(zhǔn)備模型中的對(duì)象,調(diào)用被測(cè)接口,實(shí)現(xiàn)文件方式的數(shù)據(jù)驅(qū)動(dòng)。
結(jié)果驗(yàn)證是以期望數(shù)據(jù)和接口返回?cái)?shù)據(jù)進(jìn)行對(duì)比,如果對(duì)比結(jié)果全部相等則用例成功,否則返回用例失敗。結(jié)果驗(yàn)證的內(nèi)容包括模型中數(shù)據(jù)庫表的數(shù)據(jù)集、消息事件集、異常和接口返回結(jié)果。驗(yàn)證內(nèi)容的每個(gè)屬性都要進(jìn)行對(duì)比,通過定義標(biāo)記flag 實(shí)現(xiàn)是否需要驗(yàn)證某個(gè)屬性內(nèi)容。flag 由6 元組組成,其中,Y 表示需要驗(yàn)證該屬性;N 表示不需要驗(yàn)證該屬性;C 表示該屬性作為查詢條件時(shí),返回大于0 條記錄;CN 表示該屬性作為查詢條件時(shí),返回0 條記錄;R 表示用正則表達(dá)式匹配該屬性;DS 表示對(duì)時(shí)間字段的驗(yàn)證,后面可以加毫秒數(shù)如DS500,表示和當(dāng)前時(shí)間差在500 毫秒內(nèi),滿足該范圍則驗(yàn)證通過。
某金融系統(tǒng)要實(shí)現(xiàn)其接口測(cè)試流程,先要分析出所有接口測(cè)試通用的測(cè)試流程模板基類,所有測(cè)試類繼承該流程模板基類,流程模板提供通用的測(cè)試流程框架。其次,在通用的測(cè)試流程中抽取流程模板,在該模板中實(shí)現(xiàn)部分通用方法,所有測(cè)試類可以根據(jù)實(shí)際情況重寫流程模板中方法。根據(jù)以上分析,流程模板中接口測(cè)試流程定義如下:
(1)初始化。在測(cè)試類執(zhí)行前,根據(jù)配置文件讀取數(shù)據(jù)庫配置,掃描并獲得定義的測(cè)試注解(如:測(cè)試前后清理注解、驗(yàn)證前后注解和驗(yàn)證注解等),獲取被測(cè)試接口的接口名稱、方法和參數(shù)。
(2)獲取數(shù)據(jù)驅(qū)動(dòng)。以文件的形式提供接口測(cè)試所需要的數(shù)據(jù)準(zhǔn)備。其中包括輸入?yún)?shù)、數(shù)據(jù)庫準(zhǔn)備的數(shù)據(jù)、期望數(shù)據(jù)和接口需要的上下文數(shù)據(jù)等。
(3)執(zhí)行測(cè)試。執(zhí)行測(cè)試包含測(cè)試前準(zhǔn)備、準(zhǔn)備測(cè)試數(shù)據(jù)、測(cè)試執(zhí)行、檢查結(jié)果數(shù)據(jù)、清理測(cè)試數(shù)據(jù)和測(cè)試后執(zhí)行6 個(gè)步驟。
①測(cè)試前準(zhǔn)備是抽象方法,每個(gè)用例可根據(jù)實(shí)際需要選擇是否重寫該方法。
②測(cè)試數(shù)據(jù)是對(duì)該用例執(zhí)行提供數(shù)據(jù)準(zhǔn)備,每個(gè)用例都需提前為接口運(yùn)行提供必要的數(shù)據(jù)(請(qǐng)求參數(shù)數(shù)據(jù)和數(shù)據(jù)庫數(shù)據(jù)等)。例如:測(cè)試借款接口,要準(zhǔn)備借款接口參數(shù)數(shù)據(jù)和開戶的數(shù)據(jù)庫數(shù)據(jù)。
③測(cè)試執(zhí)行是根據(jù)反射機(jī)制調(diào)用被測(cè)接口、傳遞請(qǐng)求參數(shù)數(shù)據(jù)和捕獲被測(cè)接口返回結(jié)果。
④檢查結(jié)果數(shù)據(jù)是對(duì)接口所有輸出和期望輸出進(jìn)行對(duì)比,若所有對(duì)比都成功則用例執(zhí)行成功,否則用例執(zhí)行失敗。接口輸出包括接口的返回?cái)?shù)據(jù)、數(shù)據(jù)庫變更數(shù)據(jù)、發(fā)送的異步消息數(shù)據(jù)和返回的異常,所有這些輸出都要進(jìn)行對(duì)比,保障每個(gè)用例進(jìn)行全面的驗(yàn)證。
⑤清理測(cè)試數(shù)據(jù)是對(duì)測(cè)試準(zhǔn)備的數(shù)據(jù)庫數(shù)據(jù)和接口運(yùn)行后產(chǎn)生的數(shù)據(jù)庫數(shù)據(jù)進(jìn)行清理,避免用例多次重復(fù)運(yùn)行而產(chǎn)生數(shù)據(jù)之間干擾而導(dǎo)致用例失敗。
⑥測(cè)試后執(zhí)行是抽象方法,每個(gè)用例可以根據(jù)實(shí)際情況決定是否需要執(zhí)行測(cè)試后的清理工作。
(4)結(jié)果收集驗(yàn)證。在程序運(yùn)行結(jié)束后,自動(dòng)收集運(yùn)行結(jié)果進(jìn)行對(duì)比驗(yàn)證(參見2.3 節(jié))。
測(cè)試生成以減少手工重復(fù)勞動(dòng)為目的,在開發(fā)工具IntelliJ IDEA 中開發(fā)插件,實(shí)現(xiàn)生成測(cè)試代碼、生成類模型、生成數(shù)據(jù)庫模型和生成期望結(jié)果。這4 個(gè)功能可直接在開發(fā)工具右鍵菜單中直接使用。
生成測(cè)試代碼及文件。在Velocity 模板文件中設(shè)置測(cè)試代碼模板,抽取每個(gè)接口測(cè)試不同的參數(shù),作為替換的變量。按照插件開發(fā)規(guī)范繼承相關(guān)的ACTION,當(dāng)選中某個(gè)接口時(shí)獲取接口名稱、包名等信息,替換模板中的變量,生成測(cè)試代碼的類文件、相關(guān)包和測(cè)試驅(qū)動(dòng)文件。
生成某個(gè)類的CSV 文件格式。當(dāng)選中某個(gè)類時(shí),獲取類的名稱、屬性等相關(guān)內(nèi)容,在指定包中生成類的CSV 文件。在CSV 文件中可以設(shè)置該類每個(gè)屬性多列值,作為多個(gè)用例的輸入?yún)?shù)、輸出參數(shù)和驗(yàn)證結(jié)果值。
生成數(shù)據(jù)庫表的CSV 格式。在配置文件中配置數(shù)據(jù)源相關(guān)信息,插件獲取配置信息,在界面中用戶選擇要生成的數(shù)據(jù)庫和相關(guān)表,在指定包中生成表信息的CSV 文件。在CSV 文件中可以設(shè)置表中的多條記錄,作為多個(gè)用例的數(shù)據(jù)庫準(zhǔn)備數(shù)據(jù)和數(shù)據(jù)庫期望數(shù)據(jù)。
生成接口測(cè)試產(chǎn)生結(jié)果自動(dòng)收集,攔截運(yùn)行接口時(shí)返回的結(jié)果、產(chǎn)生的SQL、異常和發(fā)送的異步消息事件,將所有結(jié)果存儲(chǔ)在臨時(shí)文件中。當(dāng)用例運(yùn)行后執(zhí)行一次,將臨時(shí)文件中的數(shù)據(jù)存儲(chǔ)到用例YMAL 文件的期望結(jié)果中,進(jìn)行人工檢查期望數(shù)據(jù)的正確性。該方式避免了所有期望數(shù)據(jù)都進(jìn)行手工填寫,提高了測(cè)試效率。后續(xù)再運(yùn)行用例時(shí),自動(dòng)對(duì)比結(jié)果正確性。
在某金融公司借款系統(tǒng)研發(fā)迭代中使用測(cè)試工具,在10 個(gè)迭代中完成20 個(gè)SOA 服務(wù)接口、2 個(gè)消息監(jiān)聽接口和4 個(gè)定時(shí)任務(wù)接口的測(cè)試任務(wù)共600個(gè)用例,從測(cè)試效率、檢錯(cuò)性、回歸保障3 方面分析實(shí)驗(yàn)結(jié)果。
測(cè)試效率:10 個(gè)迭代完成600 個(gè)用例,平均每個(gè)迭代60 個(gè)用例。由于分布式系統(tǒng)鏈路較長(zhǎng),若這些用例通過功能測(cè)試手工去完成,平均每天執(zhí)行20個(gè)用例則需要3 人。此外,用例執(zhí)行受環(huán)境穩(wěn)定性影響較大,需要從鏈路的發(fā)起端完成業(yè)務(wù),若被測(cè)系統(tǒng)處于中下游,設(shè)計(jì)的異常測(cè)試用例很難模擬或無法測(cè)試。采用接口測(cè)試工具完成,自動(dòng)生成測(cè)試代碼、生成輸入對(duì)象和生成結(jié)果,使測(cè)試人員關(guān)注在用例的設(shè)計(jì)、數(shù)據(jù)的準(zhǔn)備和結(jié)果的核對(duì)上,完成60 個(gè)用例只需4 小時(shí)。
檢錯(cuò)性:接口自動(dòng)化測(cè)試工具AutoTest[6]、SOAPUI[14]和JMeter[15]等,只能對(duì)接口返回結(jié)果的部分屬性驗(yàn)證。與其相比,本文提出的接口測(cè)試工具可以對(duì)SOA 服務(wù)和不屬于服務(wù)的異步監(jiān)聽消息和定時(shí)任務(wù)等進(jìn)行測(cè)試,檢查的輸出結(jié)果全面,可以對(duì)接口的所有輸出驗(yàn)證,包括接口返回結(jié)果、數(shù)據(jù)庫表數(shù)據(jù)、發(fā)送的異步消息事件和異常,對(duì)象的每個(gè)屬性精細(xì)化驗(yàn)證。發(fā)現(xiàn)的問題更全面,對(duì)質(zhì)量要求嚴(yán)格的金融類系統(tǒng)提供了可靠質(zhì)量保障。在10 個(gè)迭代中發(fā)現(xiàn)的缺陷類型主要有接口輸入驗(yàn)證錯(cuò)誤24個(gè)、接口內(nèi)部邏輯錯(cuò)誤15 個(gè)、接口返回結(jié)果錯(cuò)誤21個(gè)、數(shù)據(jù)庫表字段內(nèi)容錯(cuò)誤30 個(gè)和消息內(nèi)容錯(cuò)誤10 個(gè)。這些缺陷按嚴(yán)重程度分類,其中嚴(yán)重缺陷24個(gè)、一般缺陷35 個(gè)、輕微缺陷40 個(gè)。
回歸保障:隨著迭代的進(jìn)行,自動(dòng)化接口測(cè)試用例增加,可回歸用例數(shù)量也同時(shí)增加,600 個(gè)用例的運(yùn)行時(shí)間只需1 分鐘并且驗(yàn)證全面,在代碼重構(gòu)或回歸業(yè)務(wù)時(shí)提供有利質(zhì)量保障。
本文設(shè)計(jì)的自動(dòng)化測(cè)試工具,很好的解決了接口測(cè)試數(shù)據(jù)驗(yàn)證不全面及不精細(xì)問題,實(shí)現(xiàn)了接口輸入?yún)?shù)和準(zhǔn)備的數(shù)據(jù)庫數(shù)據(jù)轉(zhuǎn)換為數(shù)據(jù)驅(qū)動(dòng)文件、接口測(cè)試代碼生成、編寫測(cè)試用例可視化和接口輸出結(jié)果自動(dòng)收集等功能。工具在某金融公司得到了很好的應(yīng)用和推廣,為多個(gè)金融業(yè)務(wù)系統(tǒng)提供可靠質(zhì)量保障。