一句話,道破了改進難點所在。最近在項目中圍繞持續集成做改進的時候,對這一點感受頗深。跌跌撞撞的一路走來。我們的持續集成的過程已經變得有些“個性化”,反過頭來看我們一路的變化,非常有意思。
相關廠商內容
百度開發者大會:Web App設計、移動互聯網應用、個性化推薦、敏捷(3月23日 免費報名中!)
Visual Studio 11 Beta 和 .NET Framework 4.5 Beta版免費下載中!
軟件研發,不僅僅是持續集成
從項目的技術架構說起,我們的項目是采用的J2EE+Flex的方式進行開發的。在我進入項目組的時候,一個比較健壯的持續集成環境已經搭好了。工程分為兩個,一個是Java后端的工程,一個是Flex前端的。我們的持續集成服務器是CC。整個開發工作是圍繞著持續集成展開的。一周為一個迭代。
那個時候,我們采用的是比較標準的方式:
后臺采取TDD的方式開發。
每次提交代碼之前更新所有代碼,然后運行所有測試用例,全部為綠色的時候才提交。
前臺Flex比較麻煩,所以采取了用功能測試覆蓋單元測試的方式。用基于Ruby的FunFx寫單元測試。工作方式與后臺差不多,每次前臺功能測試全部通過了才提交。
持續集成的流程是每隔5分鐘檢測一邊代碼庫,有更新就build。
build的流程是先編譯后臺,跑單元測試,單元測試通過了,再編譯Flex,將swf和html以及后臺的文件打成war包,部署到tomcat上去,跑功能測試。
build成功之后發布到特定的目錄,形成發布列表。有war包供人下載。
那個時候,build一次大概是15分鐘,因為Check In Gate環節是按照標準流程走的,所以build出錯的幾率也小。CC大多數時候是綠的。哪怕偶爾出問題紅了,也很快被修正了。
隨著項目的開發,代碼規模越來越龐大。功能測試越來越慢,比起自動執行腳本那種速度,開發人員更樂意手動點兩下,加之上面對工作進度的壓力。更改了一些工作方式:
后臺的工作方式不變。
前臺,將功能測試腳本的工作交給幾個測試人員編寫。幾個測試人員也坐在附近,基本可以看作團隊成員(到后來編制也是我們團隊的成員了)。 開發人員人肉測試一下保證沒有問題了再提交。
測試人員寫腳本的流程是拿到上一次build成功的war包,在本地寫腳本,本地測通過了再提交。
持續集成服務器上功能測試不通過的時候,由測試人員提交BUG,開發人員修改。
持續集成的流程依舊。
這樣,從后來收集的數據看,工作效率是提升了,因為參照以前的統計,開發人員的工作一下減輕了1/3。以進度來衡量的速度自然很輕易就可以讓上級滿意了。
新的解決方案總會產生新的問題,測試人員在測試方面的專業性,使得他們寫出來的腳本測的更細。功能測試的時間占耗,增長的更快了,短短半個月,就增長到了1個小時。每當出現問題,作出反應之后,要在1個多小時以后才能知道結果。而且,持續集成方面并沒有做到,一旦出錯,誰也不能提交代碼這么嚴格。模塊化的設計所帶來的假想的安全感和進度的壓力,使得開發人員修正問題的激勵不高。于是修正問題的速度不如產生問題的速度快。持續集成服務器在那兩個個禮拜里只有兩頭是綠的,周一早晨和周五下午。
最早,我們發覺,由開發人員重構造成的腳本失敗占大多數,而測試人員每次拿到的上一個版本是沒有錯誤的。所以會出現自動化腳本本地跑得過,服務器上跑不過的情況發生。于是我們修改了發布的邏輯,在后臺單元測試通過、flash編譯完成的情況下打的那個war包,復制一份,放到某特定目錄指定為current build。供測試人員寫測腳本使用。
過程改進之后,測試人員可以快速的修正腳本了,雖然對于開發人員重構造成測試人員工作的返工無疑是一種浪費,但是畢竟自動化的測試省了回歸測試的不少時間,還是可以接受。
腳本的修正速度解決之后,工作似乎有了些起色,但很快,問題的本質就暴露了出來--build的時間太長了,修得速度還是跟不上問題產生的速度。尤其是中間缺少當build失敗時強制阻止代碼提交的環節。這之后依然是周一和周五兩頭綠,中間都是紅的。于是,我們覺得問題還是出在build速度上。我們人工的將功能測試腳本分到四個suite里去,然后以多線程的方式運行。速度被提高了4倍。于是又消停了兩天。
好景不長,多線程的測試似乎不太穩定。很多本地可以跑通的測試用例,到了服務器上就失敗。險些一個禮拜都沒有build出一個版本。最后不得不改回單線程。這時,build一次已經占到了100分鐘。第一期的產品Backlog還沒有完成1/3。
持續集成走到這里已經進入一個困境,有必要做一些更深一步的改進。經過多次討論,歸納出了幾套方案:
分冒煙測試和all test兩套測試用例集是我們當中呼聲最高的一種方案,當我的代碼提交之后在跑完所有單元測試和基本的冒煙測試之后就發布beta版,由測試人員接到beta版,進行更細致的自動化測試并帶一些人肉測試。但是反對的聲音認為,不跑完全部的測試用例就失去了持續集成的意義。而且會更降低開發人員修正 Bug的積極性。于是作為修正,支持的聲音則提出,在Check-In Gate處把關,恢復每個人提交代碼之前跑測試用例的實踐??蛇@明顯會給開發人員帶來更大的工作負擔,估計以此時的進度壓力,開發人員的安全感肯定會大幅下降。很可能會推行不下去。
另一個方案是從細節處調優,把WEB應用部署到另外一臺機器上去,或許就會穩定一些了。但是反對的聲音認為,以測試用例的這個增長速度,他早晚會不穩定的,而且可能撐不過兩周。作為修正,想考慮分布式,但是我們所有人的知識儲備中,并沒有一個人清楚CC有沒有分布式能力。所以想的是購買Cruise,但是價格的障礙就擺在眼前了,在項目前景還不是很明朗的情況下,估計很難申請到資金,但也不是不可能,只要我們敢于冒這個風險。
第三,便是更為高級的分支式開發,將版本庫劃分一下分支,以分支來搭配持續集成,以分支合并來觸發自動構建。這樣做,開發的過程就更加有板有眼,粒度可以劃分的更細??墒欠种У膭澐?,一時想不清楚。但是假設想清楚了,似乎這也使得我們的工作流程更加復雜了,做如此之大的改變,風險有多大?效果有多大?成本有多大?到底是值不值得?一時也想不清楚。
原文轉自:http://www.anti-gravitydesign.com