高冬梅,梅新奎,宿文玲,宋笑兵
(1 黑龍江財經學院 財經信息工程學院,哈爾濱 150080;2 哈爾濱工程大學 智能科學與工程學院,哈爾濱 150080)
目前,研究人員對接口自動化測試工具展開了深入研究。研究主要集中在接口自動化測試框架設計與實現、算法生成測試用例、模型驅動測試等方面。對于接口自動化測試框架設計與實現方面,文獻[1]應用Jenkins 平臺和TestNG 技術,設計并實現了移動端接口測試框架;文獻[2]應用HttpClient 和TestNG 技術,設計與實現了Web 的http 接口測試框架;文獻[3]應用Web 開發技術,設計與實現了輕量級接口測試框架;文獻[4]應用Python 語言分析線上日志,對流量進行回放,設計與實現了服務端接口測試框架。在算法生成測試用例方面,文獻[5]應用蟻群算法生成測試用例;文獻[6]應用正交實驗設計算法,生成了大批測試用例。在模型驅動測試方面,文獻[7]建立接口語義模型,對接口語義進行邏輯推理、建立規則,生成測試用例;文獻[8]建立UML 時序圖的元模型,生成測試代碼和用例;文獻[9]通過系統變更前后的UML 用例圖、類圖和活動圖變化,生成回歸用例;文獻[10]通過狀態圖生成中間模型圖,選擇相應覆蓋率標準,覆蓋圖中路徑,生成測試用例并分析覆蓋率。
然而,目前已有的自動化測試框架或工具仍然存在以下問題:
(1)只能對被測系統發布的服務或http 接口進行測試,對不屬于服務的接口無法測試。例如,定時任務和異步消息事件。
(2)接口輸出驗證不完整,只能對接口返回結果的部分參數做簡單的斷言驗證,被測接口的數據庫表變化、發送的異步消息事件和異常無法得到驗證。
(3)生成的測試用例,依賴算法或模型,表達能力有限。
為此,針對質量要求嚴格的金融分布式系統,本文提出接口自動化測試工具,對服務接口和不屬于服務接口實現測試,接口返回結果實現精準驗證。測試工具基于IntelliJ IDEA 插件開發和實現,插件支持生成測試代碼、生成測試結果、生成數據庫模型、生成類模型和編寫用例,并提供圖形化界面。
測試工具體系結構的實現,必須從被測金融分布式系統開發的體系結構入手。如圖1 所示,該系統提供開戶、借款、還款等金融類SOA 服務;接收上游系統傳遞的異步消息;可進行結息、出賬和到期扣款等系統定時任務處理。這些接口作為金融類系統重要的功能和服務,都應該從接口測試層面去保障。在原有被測接口系統體系結構中引入測試工具,測試工具和被測接口隸屬于同一個系統,系統以多模塊的方式組織在一起。這種組織方式有利于迭代過程中開發和測試使用同樣的配置管理方式,將其部署到實際生產環境中,可以對測試模塊進行打包排除。其次,這種組織方式有利于對不屬于服務的異步消息、定時任務等進行接口測試,對質量要求嚴格的金融類系統提供全面的接口測試保障。

圖1 系統體系結構Fig.1 System architecture
測試工具包括生成測試代碼、生成類模型、生成數據庫模型、生成測試結果、數據驅動和流程模板。生成測試代碼,根據接口生成測試代碼基本結構。生成類模型,根據接口輸入參數、返回結果生成類模型文件。生成數據庫模型,根據數據庫配置生成數據庫表模型。生成測試結果,根據開發接口生成的結果進行收集和驗證,接口生成的結果包括接口返回結果、數據庫變更、發送的消息和可能的異常,測試框架對這些結果進行收集后和期望的結果進行對比驗證。數據驅動的設計是為準備調用開發模塊所需要的數據,并完成開發接口的調用。流程模板的設計是為每個接口測試提供流程的模板,所有接口測試的流程都包括初始化、獲取數據驅動、執行測試和生成結果與驗證。
文獻[6]從數據模型、服務模型和計劃模型3方面建立接口測試模型;文獻[7]從服務輸入、服務輸出、服務運行參數和服務間依賴關系4 方面建立服務接口契約模型。文獻[8-10]從模型驅動測試角度,建立UML 時序圖的元模型、類圖、用例圖、活動圖和狀態圖,生成測試代碼。文獻[11]從測試接口、測試用例、測試套件、輸入輸出和前置條件定義測試模型及關系。
在以上文獻研究的基礎上,金融分布式系統接口測試模型,從基本對象模型和數據準備模型兩個方面抽象。其中,基本對象模型,用于描述接口測試中包含的對象;數據準備模型,用于描述數據準備時需要的要素。
(1)基本對象模型定義包括:表、異步消息事件和對象。
VirtualTable =<tableName,tableBaseDesc,flags tableData >
VirtualEventObject =<eventObject,eventCode,topicId>
VirtualObject =<description,objClass,object,objBaseName,objBaseDesc,flags>
其中,tableName 為表名;tableBaseDesc 為表描述;flags 為驗證標識符;tableData 為表中數據;eventObject 為事件對象;eventCode 為事件編碼;topicId 為事件ID;description 為對象的描述信息;objClass 為對象對應類;object 為對象信息;objBaseName 為基類名;objBaseDesc 為基類描述。
(2)數據準備模型定義包括:數據庫表、上下文參數、輸入參數、輸出結果、異步消息事件集合、異常和測試單元。
VirtualDataSet=<{virtualTablei}>:數據庫表集合;
VirtualParams=<{parami}>:上下文參數集合;
VirtualArgs=<{inputArgi}>:輸入參數集合;
VirtualResult=<result>:返回結果對象;
VirtualEventSet =<{virtualEventObjecti}>:異步事件對象集合;
VirtualException =<expectException>:期望異常對象;
TestUnit=<description>:數據庫表等6 種類描述信息的抽象。
數據驅動是以文件的形式提供接口測試所需要的數據,常見的數據交換格式有XML[12]、JSON、YAML[13]和CSV。本文選擇YAML 格式文件,避開了XML 文件中的各種引號和括號等,上手較快并且文件可讀性較高。YAML 文件由模型中定義的輸入參數、準備的數據集、期望的數據集、期望的消息事件集、期望的輸出結果和期望的異常組成。其中,輸入參數負責組裝接口所需要的所有參數;準備數據集負責組裝接口所需要的所有數據庫數據;期望數據集,負責被測接口數據庫表的變化期望值;期望消息事件集,負責被測接口異步消息事件的期望值;期望結果,負責被測接口返回結果的期望值;期望異常,負責被測接口產生異常的期望值。在YAML 文件中,每個測試用例都準備好這6 類元組后,將每個元組的內容轉換為數據準備模型中的對象,調用被測接口,實現文件方式的數據驅動。
結果驗證是以期望數據和接口返回數據進行對比,如果對比結果全部相等則用例成功,否則返回用例失敗。結果驗證的內容包括模型中數據庫表的數據集、消息事件集、異常和接口返回結果。驗證內容的每個屬性都要進行對比,通過定義標記flag 實現是否需要驗證某個屬性內容。flag 由6 元組組成,其中,Y 表示需要驗證該屬性;N 表示不需要驗證該屬性;C 表示該屬性作為查詢條件時,返回大于0 條記錄;CN 表示該屬性作為查詢條件時,返回0 條記錄;R 表示用正則表達式匹配該屬性;DS 表示對時間字段的驗證,后面可以加毫秒數如DS500,表示和當前時間差在500 毫秒內,滿足該范圍則驗證通過。
某金融系統要實現其接口測試流程,先要分析出所有接口測試通用的測試流程模板基類,所有測試類繼承該流程模板基類,流程模板提供通用的測試流程框架。其次,在通用的測試流程中抽取流程模板,在該模板中實現部分通用方法,所有測試類可以根據實際情況重寫流程模板中方法。根據以上分析,流程模板中接口測試流程定義如下:
(1)初始化。在測試類執行前,根據配置文件讀取數據庫配置,掃描并獲得定義的測試注解(如:測試前后清理注解、驗證前后注解和驗證注解等),獲取被測試接口的接口名稱、方法和參數。
(2)獲取數據驅動。以文件的形式提供接口測試所需要的數據準備。其中包括輸入參數、數據庫準備的數據、期望數據和接口需要的上下文數據等。
(3)執行測試。執行測試包含測試前準備、準備測試數據、測試執行、檢查結果數據、清理測試數據和測試后執行6 個步驟。
①測試前準備是抽象方法,每個用例可根據實際需要選擇是否重寫該方法。
②測試數據是對該用例執行提供數據準備,每個用例都需提前為接口運行提供必要的數據(請求參數數據和數據庫數據等)。例如:測試借款接口,要準備借款接口參數數據和開戶的數據庫數據。
③測試執行是根據反射機制調用被測接口、傳遞請求參數數據和捕獲被測接口返回結果。
④檢查結果數據是對接口所有輸出和期望輸出進行對比,若所有對比都成功則用例執行成功,否則用例執行失敗。接口輸出包括接口的返回數據、數據庫變更數據、發送的異步消息數據和返回的異常,所有這些輸出都要進行對比,保障每個用例進行全面的驗證。
⑤清理測試數據是對測試準備的數據庫數據和接口運行后產生的數據庫數據進行清理,避免用例多次重復運行而產生數據之間干擾而導致用例失敗。
⑥測試后執行是抽象方法,每個用例可以根據實際情況決定是否需要執行測試后的清理工作。
(4)結果收集驗證。在程序運行結束后,自動收集運行結果進行對比驗證(參見2.3 節)。
測試生成以減少手工重復勞動為目的,在開發工具IntelliJ IDEA 中開發插件,實現生成測試代碼、生成類模型、生成數據庫模型和生成期望結果。這4 個功能可直接在開發工具右鍵菜單中直接使用。
生成測試代碼及文件。在Velocity 模板文件中設置測試代碼模板,抽取每個接口測試不同的參數,作為替換的變量。按照插件開發規范繼承相關的ACTION,當選中某個接口時獲取接口名稱、包名等信息,替換模板中的變量,生成測試代碼的類文件、相關包和測試驅動文件。
生成某個類的CSV 文件格式。當選中某個類時,獲取類的名稱、屬性等相關內容,在指定包中生成類的CSV 文件。在CSV 文件中可以設置該類每個屬性多列值,作為多個用例的輸入參數、輸出參數和驗證結果值。
生成數據庫表的CSV 格式。在配置文件中配置數據源相關信息,插件獲取配置信息,在界面中用戶選擇要生成的數據庫和相關表,在指定包中生成表信息的CSV 文件。在CSV 文件中可以設置表中的多條記錄,作為多個用例的數據庫準備數據和數據庫期望數據。
生成接口測試產生結果自動收集,攔截運行接口時返回的結果、產生的SQL、異常和發送的異步消息事件,將所有結果存儲在臨時文件中。當用例運行后執行一次,將臨時文件中的數據存儲到用例YMAL 文件的期望結果中,進行人工檢查期望數據的正確性。該方式避免了所有期望數據都進行手工填寫,提高了測試效率。后續再運行用例時,自動對比結果正確性。
在某金融公司借款系統研發迭代中使用測試工具,在10 個迭代中完成20 個SOA 服務接口、2 個消息監聽接口和4 個定時任務接口的測試任務共600個用例,從測試效率、檢錯性、回歸保障3 方面分析實驗結果。
測試效率:10 個迭代完成600 個用例,平均每個迭代60 個用例。由于分布式系統鏈路較長,若這些用例通過功能測試手工去完成,平均每天執行20個用例則需要3 人。此外,用例執行受環境穩定性影響較大,需要從鏈路的發起端完成業務,若被測系統處于中下游,設計的異常測試用例很難模擬或無法測試。采用接口測試工具完成,自動生成測試代碼、生成輸入對象和生成結果,使測試人員關注在用例的設計、數據的準備和結果的核對上,完成60 個用例只需4 小時。
檢錯性:接口自動化測試工具AutoTest[6]、SOAPUI[14]和JMeter[15]等,只能對接口返回結果的部分屬性驗證。與其相比,本文提出的接口測試工具可以對SOA 服務和不屬于服務的異步監聽消息和定時任務等進行測試,檢查的輸出結果全面,可以對接口的所有輸出驗證,包括接口返回結果、數據庫表數據、發送的異步消息事件和異常,對象的每個屬性精細化驗證。發現的問題更全面,對質量要求嚴格的金融類系統提供了可靠質量保障。在10 個迭代中發現的缺陷類型主要有接口輸入驗證錯誤24個、接口內部邏輯錯誤15 個、接口返回結果錯誤21個、數據庫表字段內容錯誤30 個和消息內容錯誤10 個。這些缺陷按嚴重程度分類,其中嚴重缺陷24個、一般缺陷35 個、輕微缺陷40 個。
回歸保障:隨著迭代的進行,自動化接口測試用例增加,可回歸用例數量也同時增加,600 個用例的運行時間只需1 分鐘并且驗證全面,在代碼重構或回歸業務時提供有利質量保障。
本文設計的自動化測試工具,很好的解決了接口測試數據驗證不全面及不精細問題,實現了接口輸入參數和準備的數據庫數據轉換為數據驅動文件、接口測試代碼生成、編寫測試用例可視化和接口輸出結果自動收集等功能。工具在某金融公司得到了很好的應用和推廣,為多個金融業務系統提供可靠質量保障。