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