一千萬個為什麽

搜索

如何成功預先驗證更改會導致應該被捕獲的回歸?



在CI環境中,提高集成分支質量水平的常用措施之一是強制性預先提交質量驗證(通常包括構建一些工件,執行單元測試甚至某些功能/集成測試)。

然而,一些回歸(構建破壞,各種測試失敗)由CI系統驗證在完全應該由這些強制性預先驗證驗證涵蓋的區域中檢測到。

在對這些回歸進行分析時,經常聽到的一個觀點是,將發生變化的開發人員確定為回歸的根源已成功通過了所有此類驗證。而且這種說法往往得到有力證據的支持,表明:

  • 在達到最終版本的變更後,將其移植到基於分支尖端的全新工作空間中
  • 所需的構件是從頭構建的(所以構建完全正常,沒有與緩存相關的問題等)。
  • 通過了所有強制性測試,包括涉及該區域的測試,並應檢測到回歸
  • 沒有間歇的誤報影響相應的驗證
  • 將更改提交到分支時未檢測到文件合並
  • 由於新工作空間被拉出,因此分支中提交的任何其他更改都未觸及正在修改的文件

盡管正確地遵循了所有規定的流程和實踐,但軟件更改是否真的有可能導致這樣的回歸?怎麽樣?

轉載註明原文: 如何成功預先驗證更改會導致應該被捕獲的回歸?

一共有 4 個回答:

我可以想到的一種可能性是,如果開發人員在他們自己的工作站上工作,有時候虛擬框的圖像會在其工作站上運行,而您的基礎結構不會使用完全相同的圖像。

在開發功能時,開發人員需要在其工作早期添加JVM參數或對中間件進行任何更改並忘記它。

在提交之前,所有在其工作站上運行的單元/集成測試都很有用,因為共享的烘焙圖像可用於每個develloper系統。

但是當通過CI時,它失敗了,因為中間件的更改沒有實現,或者是因為開發者忘記了要求它,或者僅僅是因為負責更新基本映像/供應系統的團隊沒有該時間還是忘了更新系統。

這在CI中突破是件好事,因為它在投入生產之前就會告訴系統無法按預期工作,但有時會發現缺失的參數。

這最後一點主張避免拒絕提交,並在功能分支上打破CI,因此它不會阻止任何其他人,並且讓開發人員在需要更改時盡早解決問題,並防止將此更改忘掉流量。

FWIW,我們在這裏完成了這個工作,開發人員可以完全訪問開發機器,並且Q/A中的發布失敗了,因為參數更改已經忘記了,我們確實轉移到廚師來處理中間件的配置(現在是tomcat),以便每個人都需要改變基礎設施必須在某個地方進行編碼,並將在所有環境中進行復制。

就是這樣。生產總是不同的。真正的錢。實際負載。真正的用戶。真正的痛苦。這就是為什麽在功能標誌後面進行任何重大更改非常重要的原因。你的部署不應該改變任何東西。開啟功能是唯一應該對您的網站進行重大更改的方法。

破解始終在理論上是可能的,因為開發人員執行的提交前驗證是單獨完成的,因此無法考慮並行驗證的其他正在進行的更改。這樣的變化可能會相互幹擾並導致回歸,而在SCM級別實際上沒有可檢測到的匹配。

這種幹擾變化的一個簡單例子:

假設最新版本的項目分支中的代碼包含一個特定的函數,該函數在一個文件中定義並在其他幾個文件中調用。在該項目上並行工作的兩名開發人員正在準備對代碼進行一些更改。

開發人員重新編譯該函數,刪除或添加強制函數參數,當然還會更新所有關聯文件中函數的所有調用,以匹配更新後的定義。

開發者B決定在之前不包含任何這種調用的文件中添加對所述函數的調用,並且因此不被開發者A的改變觸及。當然,開發者B正在填充參數列表以匹配最新標簽中可見的函數定義。這是舊的定義,因為開發者A的變更尚未提交。

兩位開發人員都可以通過結果正確執行預交付驗證,然後繼續提交代碼更改。由於這兩個更改集不會觸及相同的文件,因此不會發生最終合並,這通常會表示潛在的問題,需要仔細研究並重新執行預先驗證驗證。任何事情都不能給出一個微妙的暗示,即某些事情可能會出錯。

然而,最終的結果是災難性的 - 由於開發者B添加的函數調用與開發者A更新的函數定義不匹配,構建被破壞。

當你發現這種類型的問題時,你應該寫一些新的非常快速的運行驗收測試,以消除這些問題,並將它們添加到在集成測試之前運行的構建驗證測試。您應該不斷地向左移動,並試圖縮短向開發人員提交更改的反饋循環。如果你找不到一種方法來做到這一點,那麽你的架構可能並不像它需要的那樣敏捷。

@Dan Cornilescu - 您的場景適用於緊耦合架構,這就是為什麽松散耦合的體系結構(版本化RESTful API的微服務)已成為高性能組織當前的最佳實踐。這些服務組織矩陣還有其他復雜性需要克服。

有時你需要重構整個架構來克服這些問題。我相信,由於他們以前的體系結構強加於他們,因此,Google和eBay完全將其平臺重新架構了5次(時間跨度大約為10年)。