開發運作技術:持續整合

軟體系統是對單一檔案產生的一種複雜但明顯簡單的獨立變更,這可能會對整體系統產生非預期的副作用。當大量開發人員同時在相關系統上工作時,協調程式碼更新會是一個不容易解決的問題,不同的開發人員所做的變更可能會不相容。

持續整合 (CI) 的做法就是為了解決這樣的問題所建立的。CI 遵循的原則是,如果某件工作需要花費大量的時間與精力,您就應該更頻繁地去做這件工作,強迫使您工作時更不費力。CI 可以建立快速的意見回饋循環並確保開發人員分成較小的批次工作,讓團隊做出品質更佳的軟體,降低持續開發及維護軟體的成本,同時提高團隊的生產力。

如何實施 CI

當您的機構實作 CI 時,開發人員會定期將所有工作整合到程式碼集的主版本 (又稱為「主幹」、「主程序」或「主線」)。DevOps Research and Assessment (開發運作研究與評估,DORA) 研究 (PDF) 顯示,如果開發人員至少每天將工作合併到主幹中一次,團隊的執行成果就會比較好。一組自動化測試會在合併之前與之後執行,藉以驗證變更不會導致產生迴歸錯誤。 如果這些自動化測試失敗,團隊會停止正在執行的工作,並立即修正問題。

CI 可確保軟體一直處於工作中狀態,且開發人員分支不會與主幹之間產生明顯分歧。CI 的優點很明顯:研究 (PDF) 顯示,這樣會產生更高的部署頻率、更穩定的系統,以及品質更高的軟體。

成功部署持續整合的關鍵元素如下:

  • 每一個修訂版本都應該觸發軟體的建構。
  • 每一個修訂版本都應該觸發一系列自動化測試,以在幾分鐘之內提供意見回饋。

如要部署這些元素,您必須具備下列項目:

  • 自動化建構程序。CI 的第一步是用自動化指令碼來建立可部署到任何環境的套件。透過 CI 建構建立的套件應具有權威性,並由所有下游程序使用。這些建構應予以編號並且可重複使用。您應該每天至少成功執行建構程序一次。
  • 一套自動化測試工具。如果您沒有自動化測試工具,可以先撰寫一些單元及驗收測試 (PDF),其中包含對系統而言具有高價值的功能。請確認這些測試的可靠性。如此一來,當測試失敗時,您就會知道發生了真正的問題,而如果測試通過,您就可以確信系統中沒有嚴重的問題。然後,請確認所有新功能都涵蓋在測試中。這些測試應快速執行,並儘快為開發人員提供意見回饋。您的測試應該每天至少成功執行一次。最後,如果您進行了效能與驗收測試,開發人員應該每天收到這些測試的意見回饋。
  • 在每次檢查時執行建構及自動化測試的 CI 系統。系統也應該讓團隊能夠瞭解狀態。您在這方面可能會享受到一些樂趣,例如,您可以使用警笛或號誌燈來指示建構損毀的情形。請不要使用電子郵件通知;許多人都會忽略電子郵件通知,或者建立篩選器來隱藏通知。聊天系統的通知是達成此目的的一種更好、更受歡迎的方式。

持續整合由 Kent Beck 與 Extreme Programming 社群 (這個詞就是出自此社群) 所定義,其中還包含兩個進一步的實作,經預測也可達成更高的軟體推送效能:

CI 需要自動化單元測試。這些測試所達到的全方位程度,應足以讓您確信軟體能夠依預期工作。測試也必須在幾分鐘之內執行。如果自動化單元測試需要花費更長的時間執行,開發人員就不會想要經常執行這些測試。如果不經常執行測試,就可能會從許多不同的變更中產生測試失敗的結果,使您更難以找出問題所在。不經常執行的測試很難維護。

建立多套可維護的自動化單元測試是一件複雜的工作。如要解決這個問題,一種比較好的方法是實作測試驅動開發 (TDD),開發人員可以透過這種方式撰寫一開始就失敗的自動化測試,然後再實作讓測試通過的程式碼。TDD 有幾個優點,其中一個是它可以確保開發人員寫出模組化及容易測試的程式碼,進而降低所寫出自動化測試套件的維護成本。許多機構都沒有可維護的自動化單元測試套件,但儘管如此,仍然不實作 TDD。

CI 的缺點

如前所述,CI 有時候會被視為一種具爭議性的做法。CI 需要開發人員將大型功能及其他變更切割成較小的增量步驟,以便頻繁整合到主幹中。對於不習慣這種工作方式的開發人員而言,這會改變他們的做法。此外,當團隊改成使用較小步驟時,完成大型功能會需要更長的時間。但是,一般而言,您並不會想要最佳化開發人員在分支上將大型功能宣告為完成的速度,而是想要儘快完成變更的審查、整合、測試及部署。當變更較小而且獨立,而變更所在的分支屬於短期分支時,這個程序會使軟體開發與推送的速度更快且更穩定 (PDF)。以小型批次工作也可確保開發人員定期收到有關系統工作影響的整體意見回饋,這些意見回饋分別來自於其他開發人員、測試人員與客戶,以及來自自動化效能與安全性測試。這將有助於更輕鬆、快速地偵測、分類及修正任何問題。

儘管存在這些缺點,但對於想要推動持續推送軟體更新的任何機構而言,協助軟體開發團隊實作持續整合都應該是最優先的工作。

常見陷阱

防止廣泛採用 CI 的一些常見陷阱如下所示:

  • 不會將所有內容都放進存放區。建構及設定應用程式與系統所需的任何內容都應該放進存放區。這看起來好像不在 CI 的範圍之內,但這是一個重要的基礎。
  • 不會自動化建構程序。許多步驟都會產生犯錯的機會,並且沒有為步驟留下記錄。
  • 不會對每次變更觸發快速測試。完整的端對端測試是必要的,但快速測試 (通常是單元測試) 對於提供快速意見回饋而言也很重要。
  • 不會立即修正損毀的建構。CI 有一項關鍵的目標是建立一個穩定的建構讓所有人都可以開發。如果無法在幾分鐘之內修正建構,則應找到導致建構損毀的變更並予以還原。
  • 使測試花太長時間執行。測試的執行不應超過幾分鐘的時間,據 DORA 研究 (PDF) 表示,上限約為 10 分鐘。如果您的建構耗時超過這個時間,則應改善測試的效率,並新增更多運算資源,讓您能夠平行執行測試,或者使用部署管道模式將執行耗時較長的測試分割成單獨的建構。
  • 合併至主幹的頻率不夠頻繁。許多機構都會進行自動化的測試與建構,但不會強制每日執行合併至主幹的動作。這會導致長效型分支更難以整合,而且開發人員等待意見回饋循環的時間會太長。

評估 CI 的方式

前面討論到的 CI 概念概述了在系統與開發環境中評估 CI 效益的方式,如下表所示。收集這些指標可以讓您最佳化指標的程序與工具。這樣會為開發人員產生更佳的 CI 實作以及更短的意見回饋循環。

要測試的因素 評估內容
程式碼修訂版本是否會觸發軟體的建構 在軟體建構中未經人為操作介入而產生程式碼修訂版本的百分比。
程式碼修訂版本是否會觸發一系列自動化測試 在一套未經人為操作介入而執行的自動化測試中產生程式碼修訂版本的百分比。
自動化建構與測試是否每天成功執行 每天成功執行的自動化建構百分比與自動化測試百分比。
目前建構是否可供測試人員進行探索性測試 建構對測試人員的可用性,或反之,也就是建構對測試人員的不可用性。
開發人員是否每天都會從驗收與效能測試中得到意見回饋 開發人員從驗收與效能測試中得到意見回饋的可用性,也就是測試每天提供可用意見回饋給開發人員的百分比。
是否立即修正損毀的建構 從建構損毀到修正之間所花費的時間,可能是透過檢查來修正問題,或者是透過還原損毀的變更。

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
開發運作