1. 程式人生 > >api-hook,更輕量的介面測試工具

api-hook,更輕量的介面測試工具

### 前言 在網站的開發過程中,介面聯調和測試是至關重要的一環,其直接影響產品的核心價值,而目前也有許多技術方案和工具加持,讓我們的開發測試工作更加便捷。介面作為資料傳輸的重要載體,資料格式和內容具有多樣性,從巨集觀的角度上看,分為成功和失敗,這兩種狀態又可以細分,例如失敗對應的狀態碼有5**/4**,不同的狀態碼代表的問題是不一樣的,都需要一一考慮,成功返回後,所有欄位返回結果又是排列組合形式,那麼問題就來了,是否能在條件容許的情況下快速覆蓋所有的場景呢,從技術的角度上講,問題不大,但是有時候成本卻有點高,那怎麼以一種低成本的方式快速實現呢,本文將圍繞這個問題展開討論,並嘗試提供一種解決方案。 ### 現狀 前面說到了工作中遇到的介面測試場景,當然目前也有很多工具可以幫我們實現介面的測試,如使用廣泛的postman和fiddler等工具,功能強大,可安裝外掛或自定義指令碼,解決資料測試的問題,比如我們想要mock服務,參考https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/ 即可,網上也有很多使用教程,如果願意花些時間的話,一定能給工作帶來效率的提升,好吧,前提是你要花些時間。 ### api-hook優勢 #### 1.開箱即用 有時候我只想簡單修改一下介面資料,但是需要我安裝軟體,找教程搗騰半天,時間花費了,效率卻降低了,api-hook引入專案中,通過簡單配置(真的很簡單)即可使用,所有操作所見即所得,沒有學習成本; #### 2.輕量方便 工具足夠輕量,不需要另起服務,不需要單獨維護,它就是你頁面的一部分而已,你可以像控制一個div一樣去控制它; ### 工具介紹 #### 1.)工具演示 __功能說明__ ![圖片描述](https://fulu-common-util.oss-cn-hangzhou.aliyuncs.com/wiki_assets/apihook/api-tool.jpg) 【1】是介面攔截/mock的切換區域,【2】可以關閉api-hook工具面板,【3】是工具面板顯示/隱藏開關; __介面攔截__ ![圖片描述](https://fulu-common-util.oss-cn-hangzhou.aliyuncs.com/wiki_assets/apihook/api-filter.gif) 當工具面板可見且處於介面攔截模式下,所有發起ajax請求的介面返回頁面前都會被攔截,當前處於編輯的介面處於介面請求列表第一位置,且背景有斑馬線滾動動畫,如果後續有其他介面響應被捕獲,那麼新的攔截介面處於編輯等待的狀態,背景呈現淡藍色,有底部位移動畫提示。當介面編輯完成,點選【確定】後,處於編輯等待狀態的介面會自動切換成編輯模式,當然也可以自行切換。 __介面mock__ ![圖片描述](https://fulu-common-util.oss-cn-hangzhou.aliyuncs.com/wiki_assets/apihook/api-mock.gif) 介面mock整合mockjs的功能,因此template配置可參考mockjs官網說明,這裡需要說明的是template欄位需要遵循JSON格式規範。 #### 2.)環境要求 該工具採用react開發,適用的專案也要求使用react技術框架;此外,工具會攔截所有ajax請求,因此確保你使用的介面請求是通過ajax發出的。 #### 3.)使用方式 __安裝npm包__ npm install api-hook __元件匯入__ 在專案入口檔案引入元件 ``` import ApiHook from 'api-hook'; function App() { return (
); } ...... ReactDOM.render( document.getElementById('root') ); ``` #### 4.)其他說明 __支援響應型別__ 介面的響應型別目前只支援text/json,因此介面如果是`document`,`blob`,`arraybuffer`等型別,則工具不做處理; __元件引數__ |屬性|說明|預設值| |---|---|---| |autoFilter |是否預設攔截介面 | false| |defaultVisiable |工具面板是否預設可見 |false | |allowOrigins |容許開啟工具功能的站點,為陣列型別,只有配置此項,才能在專案中使用工具 | | ### 研發介紹 #### 1.)流程設計 工具提供了兩種模式,介面mock和介面攔截,不同的模式內部流程稍有不同,具體如下: ![圖片描述](https://fulu-common-util.oss-cn-hangzhou.aliyuncs.com/wiki_assets/apihook/api-hook-1.jpg) 介面攔截模式下,所有需要被攔截的介面響應都會被api-hook劫持,而不會對請求流程做任何處理。在工具提供的介面上可以修改響應狀態碼和介面的具體內容,在介面mock模式下,就是通過mockjs實現資料的模擬,mockjs通過自定義MockXMLRequest代理所有匹配請求,實現資料的響應。 #### 2.)XMLHttpRequest代理 由於需要修改XMLHttpRequest的預設行為,因此專案程式碼實際訪問的是其代理物件,在介面攔截/mock下,都是重寫XMLHttpRequest物件,具體實現通過ajax-hook和mockjs來實現,接下來我們探究一下其中原理; __ajax-hook__ 在介面攔截模式,通過ajax-hook提供介面代理XMLHttpRequest原生物件,監聽所有原生xhr物件屬性,確保ajax-hook回撥先執行,其次是ajax請求的回撥; ``` XMLHttpRequest = function () { var xhr = new window[realXhr]; for (var attr in xhr) { var type = ""; try { type = typeof xhr[attr] } catch (e) { } if (type === "function") { // hookAjax methods of xhr, such as `open`、`send` ... this[attr] = hookFunction(attr); } else { Object.defineProperty(this, attr, { get: getterFactory(attr), set: setterFactory(attr), enumerable: true }) } } ...... } ``` __mockjs__ mockjs將原生XMLHttpRequest儲存在window._XMLHttpRequest屬性上,宣告一個MockXMLHttpRequest物件,該物件模擬了XMLHttpRequest的行為和方法,當我們使用Mock.mock(...)api時,執行window.XMLHttpRequest = XHR;這裡XHR就是MockXMLHttpRequest; __代理物件切換__ 工具在不同模式下,使用不同的代理物件,在切換攔截和mock的時候,需要執行重置原生XMLHttpRequest和初始化代理物件; ``` // mock模式 registerMock() { unProxy(); // 解除ajax-hook代理 const { mockList } = this.state; mockList.forEach(({ url, template }) => { Mock.mock(url, template); // mock註冊 }); } // 攔截模式 unRegisterMock() { if (window._XMLHttpRequest) { // mock代理,重置原生ajax物件 window.XMLHttpRequest = window._XMLHttpRequest; } ajaxProxy(); // 啟用ajax-hook代理 } ``` ### 最後 該工具可供前端開發人員和測試人員使用,力求提供一種更便捷的方式去實現資料的個性化修改。此次只推出了基礎功能,後續還將加入更多新特性,本倉庫地址:https://github.com/lanpangzi-zkg/api-hook ,如果覺得還行就點個star吧,有問題歡迎交流。 福祿ICH·架構組 福