本文依托于我們團(tuán)隊出品的 https://easy-mock.com 在線 mock 系統(tǒng)介紹一下 mock 在日常開發(fā)中所扮演的角色,介紹一下 mock 是如何影響開發(fā)效率的。
其實我們公司在很長一段時間內(nèi)都是沒有 mock 類似的服務(wù)的,甚至開發(fā)者自己也沒有自己在用的 mock 服務(wù)。按照這種沒有 mock 環(huán)節(jié)的開發(fā)形式,我們發(fā)展出了自己的一套開發(fā)流程,并且很長一段時間都固化在這個流程上,稍后我會詳細(xì)介紹下,其實不能說我們這套流程有問題,所以后面我們引入 mock 的時候,我們整理了 N 個 mock 系統(tǒng)解決的問題和帶來的便捷,但是大家卻感知非常模糊,為什么呢,因為一個軟件的開發(fā)過程本身就是個很漫長的過程,這其中優(yōu)化了一小塊流程的時候,大家最大的感知不是你解決了問題,而是你改變了習(xí)慣,這本身就是成本,所以大家會隱約覺得你不是在解決問題,而是引入了不必要的成本。
后來,我們組織了多次分享,為大家剖析 mock 在開發(fā)流程中的必要性,這是一點,另外一點非常積極的影響就是,大家的這種感知逼著我們架構(gòu)組去把這個工具做的非常自動化和方便,盡量的減少流程改變帶來的成本,減少系統(tǒng)操作上帶來的學(xué)習(xí)成本,所以后來很短的一段時間,這個系統(tǒng)就發(fā)展出了很多頗具特色的功能,而這些功能正是 easy-mock 的強(qiáng)有力的優(yōu)勢。
剛才提到,我們團(tuán)隊之前的開發(fā)流程,這里可以和大家做個簡單的分享。我們團(tuán)隊算是一個中型的創(chuàng)業(yè)團(tuán)隊,目前大概不到200名程序員,在沒有 mock 之前,其實有兩個階段,首先是早期的混亂期,項目管理并沒有一個統(tǒng)一的規(guī)范的流程的時候,這時候,通常是在本地代碼里直接寫死一些模擬數(shù)據(jù)來實現(xiàn)所謂的 mock,或者是像前端,在自己的靜態(tài)資源服務(wù)環(huán)境中建一些靜態(tài)文件來模仿接口數(shù)據(jù)(對于客戶端開發(fā)就沒這么好的事情了)。后來,團(tuán)隊變大,業(yè)務(wù)變得多起來,這時候如果沒有一個規(guī)范的開發(fā)流程,很容易失控。所以,我們制定了一些規(guī)范的流程。大體描述起來是這樣的(部分流程有出入,視實際情況而定):
需求,可行性評估(Leader參與)。
需求評審,通常是交互稿或者原型。
交互或者設(shè)計評審,確認(rèn)邏輯細(xì)節(jié)。
開發(fā)給出排期,包括(接口定義/前端開發(fā)/聯(lián)調(diào)/提測/測試時間)。
PM或架構(gòu)師系統(tǒng)和架構(gòu)分析產(chǎn)出。
服務(wù)端設(shè)計數(shù)據(jù)庫和接口,給出詳細(xì)的接口定義(swagger)。
接口評審,完成后部署開發(fā)服務(wù)器,前端可以直接按照swagger文檔請求定義的接口,返回的是完全寫死的假數(shù)據(jù)。
前后端分別開發(fā)。
聯(lián)調(diào),提測。
測試,預(yù)發(fā)。
運(yùn)維發(fā)布線上,測試回歸線上。
這個流程中較為特殊的部分,就是和 mock 相關(guān)的部分,在之前我們的流程中,被第7步替代了,我們采用的方式是,后端定義好接口后,需要在代碼中定義好空的 controller ,內(nèi)部直接 response 一個寫死的 JSON 數(shù)據(jù),然后接口評審后,將此服務(wù)部署到開發(fā)環(huán)境上,前端可以直接請求這些假的接口。
聽上去,好像也是一個完美的流程,前端不需要再自己模擬數(shù)據(jù)了,至少有一個假的接口可以調(diào)用了。那相對于獨立的 mock 服務(wù)來說有些什么問題呢?
后端定義的接口很容易滿足不了界面的需求,這時候前端在開發(fā) demo 的時候,發(fā)現(xiàn)問題需要反饋給服務(wù)端,服務(wù)端需要修改接口定義,然后重新部署服務(wù)。整個過程的溝通成本和服務(wù)重啟的成本都比較高,而且服務(wù)經(jīng)常重啟(java的重啟速度大家應(yīng)該都懂的),前端的開發(fā)會受到嚴(yán)重影響,但是時間長了之后,可能大家已經(jīng)感知不到這個效率的損耗有多大了,甚至可能很多開發(fā)還享受于這個時間的損耗(順便抽根煙什么的)。
體驗過這種開發(fā)流程之后,你會發(fā)現(xiàn),聯(lián)調(diào)這個本應(yīng)該獨立的開發(fā)流程基本貫穿到整個開發(fā)過程中去了,前后端之間沒有明顯的分界點,接口定義好了之后反正有問題前端反饋服務(wù)端修改就好了,大家就這樣不斷的發(fā)現(xiàn)問題,修改問題,然后服務(wù)端部分功能開發(fā)完成之后,會直接把一些真實的接口也部署到開發(fā)環(huán)境,于是就慢慢地有些接口替換為了真實業(yè)務(wù)邏輯,最后變成了一個邊開發(fā)邊調(diào)試的過程。但是站回獨立 mock 情況下來看,你會發(fā)現(xiàn)在前后端開發(fā)的過程中,有一個明顯的分界點是多么重要,首先對于開發(fā)本身很有必要,然后也會倒逼開發(fā)者遵守標(biāo)準(zhǔn)的規(guī)范,定義盡量完善的接口(定義過之后修改有成本),開發(fā)盡量完善的前后端代碼,并在一個明確的時間點快速聯(lián)動起來。
綜合來說,就是:在demo開發(fā)過程中,前端需要確保自己的數(shù)據(jù)模擬環(huán)境自己閉環(huán)可控(模擬的數(shù)據(jù)可控,環(huán)境可控),并且前后端之間要有一個明顯的分界點(強(qiáng)制規(guī)范開發(fā)流程,減少損耗)。
這大概是前端對于 mock 服務(wù)最強(qiáng)烈的訴求,那服務(wù)端對于 mock 有些什么需求呢?
不想在接口定義的時候手動填一堆假數(shù)據(jù)給前端用,mock 中可以根據(jù) swagger 中定義的 dto 實體的屬性的類型生成 對應(yīng)的 mock 數(shù)據(jù)。
希望在引入 mock 之后,不會對服務(wù)端的流程有任何影響。事實上,在 easy-mock 中,服務(wù)端需要做的事情和之前沒有發(fā)生任何變化,只是他們的接口需要定義的更嚴(yán)謹(jǐn),在 swagger 注解做好了之后,部署一個環(huán)境,將 swagger 的文檔地址發(fā)給運(yùn)維,運(yùn)維會自動在 easy-mock 中的公司項目中生成一個公共的 mock,無需服務(wù)端任何冗余的流程。
服務(wù)端可以盡情重啟,或者換環(huán)境,換機(jī)器,對前端的開發(fā)不會產(chǎn)生任何影響。
深入用過 easy-mock 系統(tǒng)的同學(xué)應(yīng)該可以發(fā)現(xiàn),easy-mock 在這些方面做了很多努力。
上一節(jié),我們主要介紹了一些工作流程和 mock 的一些基本理念的由來。這一節(jié),我們介紹下 easy-mock 的具體使用。
業(yè)界其實有很多 mock 的工具,有些是在線的服務(wù),有些是可以自己部署的服務(wù),而有些則直接可以集成到項目代碼中。例如最知名的阿里巴巴的RAP,事實上,這里不是想做個詳細(xì)的對比,因為用過的人就知道 easy-mock 的功能和易用性秒殺 RAP,并且 RAP 最近服務(wù)很不穩(wěn)定,感覺已經(jīng)是棄坑的趨勢。相對于一些本地自己編寫 mock 數(shù)據(jù)的方法,在線集中式服務(wù)的好處,自動生成 mock 的便捷更是不必多說,下面我們就介紹一下 easy-mock 的一些特色。
自動生成 mock,是 easy-mock 很重要的功能,在對原有開發(fā)流程低侵入方面扮演了很重要的角色。在業(yè)務(wù)開發(fā)中,服務(wù)端保持原有流程,編寫swagger注釋,最終通過 easy-mock 一鍵生成一個完整的項目,并且定義有更新時可以一鍵更新(而且在我們公司是運(yùn)維負(fù)責(zé)這個“一鍵生成”),客戶端則無需編寫 mock 接口,因為已經(jīng)根據(jù)服務(wù)端定義的各種實體和接口自動生成了 mock 規(guī)則(而不只是寫死的數(shù)據(jù)),整個開發(fā)流程被這個自動生成的功能串起來。
swagger 生成 mock,支持 1.0 和 2.0 的語法,支持集成到代碼中的 swagger 和自己手工編寫的 yaml 的 swagger 等。
具體的使用,可以見圖中標(biāo)注的位置的文檔。
easy-mock 的語法完全基于 mock.js , mock.js 其實是脫胎于 RAP 的一款阿里巴巴某大神出品的一個模擬數(shù)據(jù)生成的 JS 庫,功能非常全面,可以通過簡單的語法模擬各類常見的數(shù)據(jù)。
easy-mock 在 mock.js 上做了一些擴(kuò)展,例如:
動態(tài)接口。除了 mock.js 提供的簡單的 Function 功能可以實現(xiàn)動態(tài)的邏輯判斷之外,easy-mock 還在每個 mock 接口里注入了一些 express 的變量,例如 _req.header / _req.body / _req.query 等等,事實上 express 原來 req 上有的屬性基本都可以調(diào)用,這樣就可以寫非常動態(tài)的 mock 接口了,可以根據(jù) cookie,header,請求參數(shù) 判斷輸出不同的數(shù)據(jù)。
restful 。當(dāng)設(shè)置一個 mock 的路徑的時候,可以設(shè)置成 restful 的風(fēng)格,例如: '/api/:id'。這是 express 中 restful 的 route 的寫法,當(dāng)有一個請求進(jìn)來時,可以在 mock 語法中調(diào)用 _req.params.id 獲取到對應(yīng)的 restful 的參數(shù)。
例如:
簡單的說,easy-mock 中的項目可以分 個人項目 和 團(tuán)隊項目,個人項目可以在項目級別邀請別人參與共享,而團(tuán)隊項目則可以在團(tuán)隊級別邀請別人參與,這樣所有人都會共享這個團(tuán)隊中的所有項目。
以此為基礎(chǔ),可以方便的在團(tuán)隊中使用 easy-mock,在我們公司也是如此,內(nèi)部的 easy-mock 中有一個預(yù)先建好的大搜車的團(tuán)隊,默認(rèn)邀請了所有人,所以公司內(nèi)的項目都可以直接共享。
easy-mock 還有很多不容易被感知到的功能,例如:
swagger 修改后的智能覆蓋規(guī)則,如果有一個接口被修改,不會粗暴的覆蓋用戶的修改,而是會判斷用戶是否修改過,如果修改過,就不會覆蓋,如果沒有改,才會覆蓋。
根據(jù) swagger 生成前端的 class model,而且?guī)в凶⑨?,?xì)心的同學(xué)可以發(fā)現(xiàn)這個功能。
可以查看接口在 swagger 中定義的入?yún)⒑统鰠?,其實完全可以拋棄?swagger 本身的界面了。
其他有趣的功能,還待大家自己去發(fā)掘額。
最后分享一個問題,mock 除了在正常的開發(fā)流程中扮演不可或缺的角色之外,還能做些什么事情呢?
單元測試,開發(fā)在寫單測的時候,不可能用一個不穩(wěn)定的服務(wù)來調(diào)用接口,這時候需要模擬一些調(diào)用的話,就可以用 easy-mock ,這個場景其實很常用。
自動化測試,這里說的測試不是開發(fā)自己的單測,主要是指測試團(tuán)隊在做一些常規(guī)的自動化測試的時候,如果開發(fā)的接口還沒有跑通,可以用 mock 先讓測試腳本跑通,最后再對接到真正的接口上。
其他一些內(nèi)部系統(tǒng)之間調(diào)用的 mock,甚至服務(wù)端之間的 mock,為此,easy-mock 未來可能會支持一些服務(wù)端的通訊協(xié)議。
關(guān)于 easy-mock 的介紹就先到這里了,關(guān)于開發(fā)流程以及 easy-mock 的使用,大家有問題可以加 QQ 群咨詢:595325417
感謝 Vue,Vue Server Render,ElementUI,mock.js 等開源項目,這也是 easy-mock 所使用的技術(shù)棧。
GitChat是一種全新的閱讀/寫作互動體驗產(chǎn)品。一場Chat包含一篇文章和一場為文章的讀者和作者定制的專屬線上交流。本文出自Chat話題《如何用 Mock 提高開發(fā)效率》。
GitChat
一種全新的IT知識學(xué)習(xí)方式
聯(lián)系客服