Q: 我的產(chǎn)品是電信級(jí)的設(shè)備, 幾百人分成幾十個(gè)項(xiàng)目組在開(kāi)發(fā), 各個(gè)項(xiàng)目組進(jìn)度不統(tǒng)一, 如何集成?
A: 你要做的其實(shí)跟技術(shù)無(wú)關(guān), 更多的是管理工作, 就是制定你的產(chǎn)品級(jí)別的集成策略.
這涉及到需求分析和發(fā)布計(jì)劃(依賴管理, 價(jià)值和風(fēng)險(xiǎn)識(shí)別), 開(kāi)發(fā)方法(自頂向下還是自底向上, 橫向分層還是垂直特性),
集成粒度劃分(完整特性的集成還是API的集成), 集成間隔計(jì)劃, 版本控制策略, 還有尤為重要的集成測(cè)試/驗(yàn)證策略, 甚至你的決心.
任何集成策略在執(zhí)行過(guò)程中都會(huì)遇到困難, 如遲遲得不到能夠成功集成的版本. 這時(shí)你要找出原因, 并有權(quán)力或相應(yīng)措施要求整個(gè)幾百人的團(tuán)隊(duì)停下來(lái),
做為第一優(yōu)先級(jí)的任務(wù)去修復(fù). 并讓整個(gè)團(tuán)隊(duì)清楚進(jìn)度停滯造成的損失. 這么做的意圖是強(qiáng)調(diào)集成的重要性, 因此每個(gè)項(xiàng)目組在開(kāi)發(fā)時(shí), 都會(huì)優(yōu)先考慮與其它部分的集成,
從而促進(jìn)更好的溝通和反饋, 減少集成失敗的次數(shù), 縮小集成的間隔.
這在某種程度上會(huì)給你的設(shè)計(jì)帶來(lái)正面影響. 比如為了更容易的集成, 模塊間使用松耦合的協(xié)議/消息, 或者標(biāo)準(zhǔn)的數(shù)據(jù)格式來(lái)代替緊耦合的API調(diào)用.
定義可擴(kuò)展的接口來(lái)隔離實(shí)現(xiàn)修改的影響...
用集成來(lái)驅(qū)動(dòng)你的開(kāi)發(fā)進(jìn)程.
Q: 項(xiàng)目組在各自的分支上工作, 每次光合并版本就好幾天, 怎么做持續(xù)集成?
A: 改變分支策略, 使用同一分支, 隨時(shí)集成
Q: 構(gòu)建一次, 包括編譯鏈接, 測(cè)試, 需要幾十個(gè)小時(shí), 怎么集成?
A: 其實(shí)就是一速度的問(wèn)題, 有很多潛在的優(yōu)化措施
- 優(yōu)化源文件依賴關(guān)系, 該調(diào)整設(shè)計(jì)就調(diào)整設(shè)計(jì)
- 優(yōu)化構(gòu)建腳本
- 優(yōu)化測(cè)試用例, 能夠共用一套測(cè)試環(huán)境的就一起跑
- 分類測(cè)試用例, 優(yōu)先運(yùn)行價(jià)值大速度快的用例; 價(jià)值小又耗時(shí)的測(cè)試運(yùn)行間隔可以放大
- 分布式構(gòu)建, 使用諸如 Cruise 或 IncrediBuild 之類的軟件.
- 使用高性能主機(jī)
Q: 硬件依賴, 尤其是嵌入式, 怎么集成?
A: 理想的情況是: 產(chǎn)品代碼運(yùn)行在真實(shí)的嵌入式設(shè)備上, 測(cè)試結(jié)果可以報(bào)告給運(yùn)行在 PC 上的 CI 工具
我們很多項(xiàng)目早已做到這一點(diǎn), 方法也不難:
- 通過(guò)設(shè)備支持的方式(如FTP)將編譯后的代碼上傳到設(shè)備
- 向設(shè)備發(fā)出命令加載新代碼(TCP或串口)
- 運(yùn)行測(cè)試用例: 可以運(yùn)行在 PC 上通過(guò)網(wǎng)絡(luò)(TCP或串口)與設(shè)備交互以斷言其行為, 或直接運(yùn)行在設(shè)備里, 然后將測(cè)試運(yùn)行結(jié)果通過(guò)網(wǎng)絡(luò)取回
- 在硬件不具備的情況下, 使用仿真模式設(shè)備
Q: 構(gòu)建結(jié)束前有新的commit, 是否要等待上次構(gòu)建結(jié)束才進(jìn)行新的構(gòu)建?
A: 取決于你用的CI工具, 大部分是這樣的. 但在支持分布式構(gòu)建的CI工具中, 可以使用另外一臺(tái)機(jī)器來(lái)立刻運(yùn)行新的構(gòu)建, 這是一種可能的特性,
如果你知道哪個(gè)工具實(shí)現(xiàn)了它, 請(qǐng)告訴我.
對(duì)這種特性的爭(zhēng)論在于一旦構(gòu)建失敗, 將不容易分清是誰(shuí)的提交造成的, 但兩個(gè)原因這個(gè)假設(shè)不成立:
- 大多 CI 工具基于輪詢的機(jī)制, 總會(huì)發(fā)生一次構(gòu)建包含多次提交的情況
- 在提交紀(jì)律嚴(yán)明, 有責(zé)任心, 視 CI 為第一要?jiǎng)?wù)的敏捷團(tuán)隊(duì), 提交前都會(huì)在本地運(yùn)行構(gòu)建, CI server 上構(gòu)建失敗的幾率不高.
Q: 我們的產(chǎn)品需要支持多種操作系統(tǒng), CI 怎么做?
A: 多數(shù) CI 服務(wù)器都能運(yùn)行在多種操作系統(tǒng)上, 差別只在于是分別管理(單機(jī)構(gòu)建)還是統(tǒng)一管理(分布式構(gòu)建).
Q: 是否團(tuán)隊(duì)每個(gè)人都需要在自己的開(kāi)發(fā)機(jī)器上運(yùn)行 CI 集成環(huán)境?
A: 不需要運(yùn)行 CI 環(huán)境, 只需要運(yùn)行 CI 環(huán)境運(yùn)行的構(gòu)建腳本. 本地構(gòu)建使用與 CI 相同的構(gòu)建腳本將減少 CI 失敗的概率, 參見(jiàn)<<Publish
with a Publisher>>.
Q: 是否團(tuán)隊(duì)每個(gè)人都需要掌握 CI 知識(shí)?
A: CI 工具本身其實(shí)很簡(jiǎn)單, 更加重要的是整個(gè)團(tuán)隊(duì)的集成策略.
Q: 如果測(cè)試先行, 那集成環(huán)境中如何處理預(yù)先寫的肯定會(huì)失敗的測(cè)試?
A: 測(cè)試先行的另一個(gè)約束是步子盡可能小, 基本上你不應(yīng)該在讓測(cè)試通過(guò)前提交它.
Q: 可我們的測(cè)試人員提前寫的自動(dòng)化集成測(cè)試, 一開(kāi)始是失敗的, 只是隨著開(kāi)發(fā)的進(jìn)行, 才逐漸通過(guò)的. 這怎么辦?
A: 這基本上是你的測(cè)試管理策略, 一種簡(jiǎn)單的方案就是分開(kāi)存放注定失敗的測(cè)試和已經(jīng)實(shí)現(xiàn)對(duì)應(yīng)功能的測(cè)試, 隨著特性的不斷完工, 逐漸的移動(dòng)測(cè)試.
自動(dòng)化測(cè)試工具支持使用標(biāo)記來(lái)控制運(yùn)行時(shí)忽略/跳過(guò)某些測(cè)試.
Q: CI的愿景是好的, 但我們這里根本不可能, 我們的產(chǎn)品需要復(fù)雜的運(yùn)行環(huán)境, 運(yùn)行時(shí)需要人工干預(yù), 怎么測(cè)?
A: 我不清楚你說(shuō)的復(fù)雜具體是怎么復(fù)雜, 人工干預(yù)是怎么樣的干預(yù), 但這確實(shí)是個(gè)常見(jiàn)的, 有無(wú)數(shù)種真實(shí)情形的問(wèn)題. 通常我們會(huì)具體問(wèn)題具體分析,
但有幾個(gè)通用的原則:
- 設(shè)計(jì), 分離核心業(yè)務(wù)邏輯與外部界面, 爭(zhēng)取讓業(yè)務(wù)邏輯環(huán)境無(wú)關(guān)
- 自動(dòng)化, 尋找合適的自動(dòng)化測(cè)試工具, 必要時(shí)自己開(kāi)發(fā)
- 盡可能搭建真實(shí)的運(yùn)行環(huán)境
集成在很大程度上依賴你的測(cè)試策略和自動(dòng)化程度.
Q: 你說(shuō)集成依賴于測(cè)試策略和自動(dòng)化程度, 是否不運(yùn)行測(cè)試的集成不能算集成?
A: 任何一點(diǎn)集成方面的努力都是值得肯定的, 哪怕即使只是持續(xù)編譯. 事實(shí)上在那些不得不常年維護(hù)大型遺留系統(tǒng)的公司, 即使只是持續(xù)編譯,
保證每天能夠編譯通過(guò), 也已經(jīng)具有很大的價(jià)值了. 當(dāng)然, 我們需要盡可能的集成更多的自動(dòng)化檢驗(yàn)工作.
CI 社區(qū)最近出現(xiàn)了一個(gè)出于商業(yè)目的攻擊,
1,
2, 基調(diào)就是對(duì)持續(xù)編譯這種 CI 的壞味道/反模式的鄙視. 其實(shí)沒(méi)人認(rèn)為 持續(xù)集成的核心是持續(xù)編譯, 我們尊重任何集成方面的努力, 凡事總有第一步.
Q: 集成與測(cè)試, 是否經(jīng)過(guò)集成的就是可用的?
A: 取決于你如何定義可用. 信心來(lái)自于全面的測(cè)試.
Q: 聽(tīng)說(shuō) CI 環(huán)境配置挺麻煩, 有沒(méi)有簡(jiǎn)單一點(diǎn)的工具?
A: 軟件業(yè)又不是電信, 其競(jìng)爭(zhēng)激烈殘酷, 如果一個(gè)工具配置起來(lái)麻煩, 早就有更簡(jiǎn)單的代替它了. 下載試用, 再配合搜索引擎,
一天之內(nèi)你肯定能找到合適自己的工具. 如果沒(méi)有, 那么是一個(gè)機(jī)會(huì), 你可以創(chuàng)造一個(gè)更好的.
Q: 對(duì) CI 工具本身, 我還是想不清楚, 它怎么知道去哪里取代碼? 怎么知道有沒(méi)有更新? 怎么取代碼? 怎么編譯? 怎么知道跑什么測(cè)試? 怎么知道成功失敗?
A: 版本控制系統(tǒng)的客戶端都是可用的工具, 也都提供了公開(kāi)德協(xié)議或交互接口, 這都沒(méi)問(wèn)題. 至于編譯和測(cè)試, CI 工具確實(shí)不必知道,
盡管很多工具都能按照某種約定或自動(dòng)識(shí)別你的源代碼和測(cè)試. 事實(shí)上, CI 工具只是忠實(shí)的運(yùn)行你配置的行為, 通常是某個(gè)你編寫的腳本,
因此是由你來(lái)指定如何編譯和如何測(cè)試. 至于成功或失敗, CI 遵循操作系統(tǒng)的慣例, 返回值0成功, 非0失敗.
Q: 我們的版本控制系統(tǒng)是 ClearCase, 你們的 CI 工具支持嗎?
A: 不支持, 換 Subversion 吧
- ClearCase 慢
- ClearCase 貴
- ClearCase 難用
- ClearCase 太悲觀, 鎖的你沒(méi)脾氣
Q: 怎樣才能減少 CI 構(gòu)建失敗的幾率?
A: 這其實(shí)是個(gè)最佳實(shí)踐的問(wèn)題, 比如對(duì)于需要在多個(gè)操作系統(tǒng)上運(yùn)行的產(chǎn)品,
項(xiàng)目組內(nèi)不同的開(kāi)發(fā)者盡可能使用不同的目標(biāo)平臺(tái)開(kāi)發(fā),這樣可以在本地構(gòu)建時(shí)捕捉到平臺(tái)類的錯(cuò)誤. 關(guān)于CI工具CC的最佳實(shí)踐, 可參考http://blog.csdn.net/gongflow
Q: 我們?cè)谶z留項(xiàng)目上工作, 面臨前面提到的所有問(wèn)題: 編譯速度/環(huán)境依賴/多個(gè)項(xiàng)目組進(jìn)度依賴/分支合并/甚至版本系統(tǒng)用的都是ClearCase,
總感覺(jué)你說(shuō)的很虛, 未必就能給我們的現(xiàn)狀帶來(lái)多大改善
A: 這是投入產(chǎn)出比的問(wèn)題(你的項(xiàng)目還要維護(hù)多久, 能帶來(lái)多大利潤(rùn), 花費(fèi)大力氣去改善值不值得), 也是價(jià)值觀的問(wèn)題(是放任現(xiàn)狀,直到它自然滅亡,
還是逐步改善, 看看最后能改到什么程度). 我是建議試試, 從最簡(jiǎn)單的,對(duì)環(huán)境要求不高的開(kāi)始做起, 慢慢擴(kuò)大范圍. 所有的軟件都會(huì)被廢棄, 人也會(huì)死亡,
意義只在于不斷的嘗試, 看看會(huì)發(fā)生什么. 如果明知不值得, 這樣也就算了, 留點(diǎn)時(shí)間去嘗試別的事情.