共用方式為


使用單元測試向左移位測試

測試有助於確保程式代碼如預期般執行,但建置測試所需的時間和精力會花費時間遠離其他工作,例如功能開發。 透過這項成本,請務必從測試中擷取最大值。 本文討論DevOps測試原則,著重於單元測試和左移測試策略的價值。

用來撰寫大部分測試的專用測試人員,而且許多產品開發人員並未瞭解如何撰寫單元測試。 撰寫測試似乎太困難或工作太多。 對於單元測試策略是否運作、撰寫不佳單元測試的不良體驗,或擔心單元測試會取代功能測試,可能會產生懷疑。

Graphic that describes arguments about adopting unit testing.

若要實作 DevOps 測試策略,請務實並專注於建立勢頭。 雖然您可以堅持對新程式碼或可完全重構的現有程式代碼進行單元測試,但舊版程式代碼基底允許某些相依性可能很合理。 如果產品程序代碼的重要部分使用 SQL,允許單元測試相依於 SQL 資源提供者,而不是 模擬 該層可能是一種短期的進度方法。

隨著 DevOps 組織成熟,領導階層更容易改善程式。 雖然可能會有一些改變的阻力,但敏捷式組織重視明顯支付股息的變更。 透過較少的失敗,銷售更快速測試執行的願景應該很容易,因為它意味著透過特徵開發投入更多時間來產生新的價值。

DevOps 測試分類法

定義測試分類法是 DevOps 測試程式的重要層面。 DevOps 測試分類法會依其相依性分類個別測試,以及執行所花費的時間。 開發人員應該瞭解在不同案例中使用的正確測試類型,以及哪些測試程式的不同部分需要。 大部分的組織會將測試分類為四個層級:

  • L0L1 測試是 單元測試,或測試相依於受測元件中的程式碼,而沒有其他測試。 L0 是快速記憶體內部單元測試的廣泛類別。
  • L2可能需要元件和其他相依性的功能測試 ,例如 SQL 或文件系統。
  • L3 功能測試會針對可測試的服務部署執行。 此測試類別需要服務部署,但可能會針對金鑰服務相依性使用 存根
  • L4 測試是針對生產環境執行的受限制整合測試類別。 L4 測試需要完整的產品部署。

雖然適合所有測試隨時執行,但不可行。 Teams 可以選取 DevOps 程式中執行每個測試的位置,並使用 shift-left 或 shift-right 策略,在程式中稍早或更新版本移動不同的測試類型。

例如,預期開發人員在認可之前一律會透過 L2 測試執行,如果 L3 測試執行失敗,提取要求會自動失敗,而且如果 L4 測試失敗,部署可能會遭到封鎖。 特定規則可能會因組織而異,但對組織內的所有小組強制執行預期,會讓每個人都朝著相同的品質願景目標邁進。

單元測試指導方針

設定 L0 和 L1 單元測試的嚴格指導方針。 這些測試必須非常快速且可靠。 例如,元件中每個 L0 測試的平均運行時間應該小於 60 毫秒。 元件中每個 L1 測試的平均運行時間應該小於 400 毫秒。 此層級沒有任何測試應超過 2 秒。

一個 Microsoft 小組在不到六分鐘內平行執行超過 60,000 個單元測試。 其目標是將此時間縮短為不到一分鐘。 小組會使用下列圖表之類的工具追蹤單元測試運行時間,並針對超過允許時間的測試檔案 Bug。

Chart that shows continuous focus on test execution time.

功能測試指導方針

功能測試必須獨立。 L2 測試的重要概念是隔離。 適當的隔離測試可以在任何序列中可靠地執行,因為它們可以完全控制其執行環境。 測試開始時必須知道狀態。 如果某個測試建立了數據,並將它留在資料庫中,它可能會損毀另一個依賴不同資料庫狀態的測試執行。

需要使用者身分識別的舊版測試可能已呼叫外部驗證提供者來取得身分識別。 這種做法引進了數個挑戰。 外部相依性可能不可靠或暫時無法使用,會中斷測試。 這種做法也會違反測試隔離原則,因為測試可能會變更身分識別的狀態,例如許可權,導致其他測試出現非預期的默認狀態。 請考慮在測試架構內投資身分識別支援,以避免這些問題。

DevOps 測試原則

為了協助將測試組合轉換為新式DevOps程式,請闡明品質願景。 在定義及實作 DevOps 測試策略時,Teams 應遵守下列測試原則。

Diagram that shows an example of a quality vision and lists test principles.

向左移以稍早測試

測試可能需要很長的時間才能執行。 隨著專案的規模調整,測試編號和類型會大幅增加。 當測試套件成長為需要數小時或數天才能完成時,他們可以更遠地推送到最後一刻執行為止。 測試的程式代碼品質優點要等到認可程式代碼很久之後才會實現。

長時間執行的測試也可能會產生耗時調查的失敗。 Teams 可以建置失敗的容錯,特別是在短期衝刺初期。 這種容忍度會破壞測試的價值,以深入瞭解程式代碼基底品質。 長時間執行的最後一分鐘測試也增加了不可預測性,以結束短期衝刺的預期,因為必須支付未知數量的技術債務,才能獲得可寄送的程序代碼。

將測試向左移位的目標是執行管線稍早的測試工作,以將品質上移。 透過測試和程式改善的組合,左移可減少測試執行所需的時間,以及週期稍後失敗的影響。 向左移可確保在變更合併至主要分支之前已完成大部分的測試。

Diagram that shows the move to shift-left testing.

除了將某些測試責任轉移到左側以改善程式碼品質之外,小組還可以將其他測試層面向右轉移,或稍後在 DevOps 週期中,以改善最終產品。 如需詳細資訊,請參閱 向右移位以在生產環境中進行測試。

以最低的可能層級撰寫測試

撰寫更多單元測試。 偏好具有最少外部相依性的測試,並著重於在組建中執行大部分的測試。 請考慮平行建置系統,一旦元件和相關聯的測試卸除,就可以針對元件執行單元測試。 在此層級測試服務的各個層面並不可行,但原則是,如果能產生與較重功能測試相同的結果,則使用較輕的單元測試。

目標為測試可靠性

不可靠的測試對於維護的組織成本很高。 這種測試會直接針對工程效率目標運作,方法是自信地進行變更。 開發人員應該能夠在任何地方進行變更,並快速獲得任何中斷的信心。 維護高階可靠性。 禁止使用UI測試,因為它們往往不可靠。

撰寫可在任何地方執行的功能測試

測試可能會使用專為啟用測試而設計的特製化整合點。 這種做法的其中一個原因是產品本身缺乏可測試性。 不幸的是,這類測試通常取決於內部知識,並使用從功能測試的觀點來看並不重要的實作詳細數據。 這些測試僅限於具有執行測試所需的秘密和設定的環境,這通常不包括生產部署。 功能測試應該只使用產品的公用 API。

設計可測試性的產品

在成熟的 DevOps 程式中,組織會完整檢視在雲端頻率上提供優質產品的意義。 以強式方式轉移平衡,有利於單元測試與功能測試,需要小組做出支援可測試性的設計與實作選擇。 有不同的想法,構成設計良好且實作良好的程式代碼以供測試,就像有不同的程式碼樣式一樣。 原則是,設計可測試性必須成為設計與程式代碼質量討論的主要部分。

將測試程式代碼視為產品代碼

明確指出測試程式代碼是產品代碼,可清楚指出測試程式代碼的品質與產品代碼一樣重要。 Teams 應該以處理產品代碼的相同方式處理測試程式代碼,並將相同的護理層級套用至測試和測試架構的設計和實作。 這項工作類似於管理組態和 基礎結構即程序代碼。 若要完成,程式代碼檢閱應該考慮測試程序代碼,並將它保留至與產品名稱相同的品質列。

使用共用測試基礎結構

降低使用測試基礎結構來產生受信任質量訊號的列。 檢視測試為整個小組的共享服務。 將單元測試程式代碼與產品一起儲存,並以產品建置。 在建置程式中執行的測試也必須在 Azure DevOps 等開發工具下執行。 如果測試可以在從本機開發到生產環境的每個環境中執行,則其可靠性與原始程式碼相同。

讓程式代碼擁有者負責測試

測試程式代碼應該位於存放庫中的產品名稱旁邊。 若要讓程式代碼在元件界限進行測試,請將測試的責任推送至撰寫元件程式代碼的人員。 不要依賴其他人來測試元件。

案例研究:使用單元測試向左移

Microsoft 小組決定以新式 DevOps 單元測試和左移程式取代其舊版測試套件。 小組追蹤了三周衝刺的進度,如下圖所示。 圖表涵蓋短期衝刺 78-120,代表 126 周的 42 個短期衝刺,或大約兩年半的努力。

該小組從短期衝刺 78 的 27K 舊版測試開始,並在 S120 達到零個舊版測試。 一組 L0 和 L1 單元測試取代了大部分舊的功能測試。 新的 L2 測試取代了一些測試,並刪除了許多舊的測試。

Diagram that shows a sample test portfolio balance over time.

在需要兩年多時間才能完成的軟體旅程中,從程式本身學到很多東西。 總的來說,在兩年內完全重做測試系統的努力是一項巨大的投資。 並非所有功能小組都同時執行工作。 整個組織內的許多小組在每次短期衝刺中投入時間,而在某些短期衝刺中,大部分都是小組所做的。 雖然很難衡量班次的成本,但對於球隊的質量和績效目標來說,這是一個不可談判的要求。

開始使用

一開始,團隊就離開了舊的功能測試,稱為 TRA 測試。 小組希望開發人員購買撰寫單元測試的想法,特別是針對新功能。 重點是盡可能輕鬆地撰寫 L0 和 L1 測試。 小組需要先開發該功能,並建立勢頭。

上圖顯示單元測試計數開始提前增加,因為小組看到撰寫單元測試的優點。 單元測試更容易維護、更快速地執行,而且失敗次數較少。 輕鬆取得在提取要求流程中執行所有單元測試的支援。

小組直到衝刺 101 才專注於撰寫新的 L2 測試。 與此同時,TRA 測試計數從Sprint 78下降到101的27,000到14,000。 新的單元測試取代了一些 TRA 測試,但許多測試只是根據小組分析其用途而遭到刪除。

TRA 測試從 2100 跳到短期衝刺 110 中的 3800 個,因為來源樹狀結構中發現了更多測試,並新增至圖形。 事實證明,測試一直在執行,但未正確追蹤。 這不是一場危機,但請務必視需要誠實和重新評估。

更快

一旦團隊有一個 持續整合(CI) 信號,非常快速和可靠,它成為產品品質的受信任指標。 下列螢幕快照顯示提取要求和 CI 管線運作,以及經歷各種階段所需的時間。

Diagram that shows the pull request and rolling CI pipeline in action.

從提取要求到合併大約需要 30 分鐘的時間,其中包括執行 60,000 個單元測試。 從程式代碼合併到 CI 組建大約 22 分鐘。 CI 的第一個品質訊號 SelfTest 大約經過一個小時。 然後,大部分產品都會使用建議的變更進行測試。 在從 Merge 到 SelfHost 的兩小時內,會測試整個產品,並準備好進入生產環境。

使用計量

小組會追蹤計分卡,例如下列範例。 概括而言,計分卡會追蹤兩種類型的計量:健康情況或債務,以及速度。

Diagram that shows a metrics scorecard for tracking test performance.

針對即時網站健康情況計量,小組會追蹤偵測的時間、緩和時間,以及小組所攜帶的修復項目數目。 修復專案是小組在即時網站回顧中識別的工作,以防止類似事件重複發生。 計分卡也會追蹤小組是否在合理的時間範圍內關閉修復專案。

針對工程健康情況計量,小組會追蹤每個開發人員的作用中 Bug。 如果小組每個開發人員有五個以上的 Bug,小組必須在新功能開發之前優先修正這些錯誤。 小組也會追蹤特殊類別的過時 Bug,例如安全性。

工程速度計量會測量持續整合和持續傳遞管線不同部分的速度。 整體目標是提高 DevOps 管線的速度:從想法開始,讓程式代碼進入生產環境,並從客戶接收數據。

下一步