聯(lián)調(diào)之痛
最近站會時,經(jīng)常聽見開發(fā)人員說某Story已經(jīng)開發(fā)完了,等待聯(lián)調(diào),然后就沒有然后了。對于聯(lián)調(diào)時間點近的,開發(fā)人員會等一等,一天的時間很快就過去了;時間點遠(yuǎn)的,開發(fā)就領(lǐng)新story了,等另一端開發(fā)完,已經(jīng)若干天過去了。我總覺得其中有什么問題,但是說不出來。上周去QCon聽了韓老師的分享,突然發(fā)現(xiàn)這種聯(lián)調(diào)在以前團(tuán)隊的也是有的。只不過我們的解決方式不一樣,所以問題沒有這么突出。
產(chǎn)生問題的原因很簡單,現(xiàn)在的軟件開發(fā),因為系統(tǒng)復(fù)雜性提升,模塊拆分也很普遍,很難形成一個團(tuán)隊做端到端交付,沒有任何外部依賴。典型場景是模塊A由一個團(tuán)隊1開發(fā),模塊B由團(tuán)隊2開發(fā)。這時,團(tuán)隊A的功能開發(fā)完成后必須要和團(tuán)隊B開發(fā)的相應(yīng)功能聯(lián)調(diào)。目的是走一個端到端的流程,確認(rèn)功能正確。
問題也來了,
-
團(tuán)隊1和團(tuán)隊2的開發(fā)計劃多是獨立制定,很難做到同一功能在兩個模塊上同時開發(fā)完成,之間沒有任何等待。開發(fā)快的要等開發(fā)慢的,一方的story雖然開發(fā)完了,但不能進(jìn)入測試,延長了交付時間。
-
等測試發(fā)現(xiàn)bug時,已經(jīng)過去一兩天甚至更久,開發(fā)在做其他功能。回來解決問題,又要上下文切換,再度浪費時間。
-
同時聯(lián)調(diào)發(fā)生問題時,定位問題還需要花一番功夫。
之前的項目中我們使用一種契約測試(Contract Testing)的方法來解決這個問題。
-
首先,兩個團(tuán)隊確定接口具體格式,這組格式就相當(dāng)于一組契約,而后兩個團(tuán)隊根據(jù)這個契約開發(fā)各自功能。
-
同時,作為消費方的團(tuán)隊1為這個接口添加一組自動化測試,確保模塊B的功能符合契約。每次模塊B的代碼改動都會觸發(fā)這組測試,測試通過時意味著生產(chǎn)者為消費者提供了正確的功能,反之不能。這樣模塊B的改動肯定不會影響模塊A,即便有影響,也可以通過測試在第一時間反映出來。
這種方法,節(jié)省了開發(fā)人員的聯(lián)調(diào)時間,QA直接測試端到端的功能。同時遇到問題時也很容易定位問題產(chǎn)生根源。
這種測試與模塊A自身的單元測試不同,著眼點在確保模塊外部依賴的正確性。有了這層保障,模塊A的單元測試就可以使用Test Double(Fake、Mock等),構(gòu)造出更關(guān)注于自身邏輯的測試集,提高測試的運行速度和穩(wěn)定性。
采用這種方法時有兩個問題需要考慮,
-
誰來寫測試 - 這個回答相對簡單,一定要由消費者來寫,這樣才能確保測試代碼和產(chǎn)品代碼采用相同的調(diào)用方式。
-
如何組織測試 - 有兩種方式可以選擇,放在消費者端,每個消費者維護(hù)自己的一套測試;或放在生產(chǎn)者一端,每個模塊維護(hù)一套針對本模塊的測試。第一種方式更容易引起相關(guān)消費者團(tuán)隊的重視,針對性更強,但會引入一定的代碼重復(fù),第二種正相反。為了更快更有針對性的發(fā)現(xiàn)問題,我所在的團(tuán)隊使用了第一種方法。
在寫這個的時候,順便搜了一下,發(fā)現(xiàn)了老馬的這篇文章IntegrationContractTest,基本思想類似,實現(xiàn)上稍有不同。最后總結(jié)一下,手工聯(lián)調(diào)這種費時費力的工作,能少做就少做,能自動化就自動化,搞軟件的生命短暫,浪費在這上不值。