前端自動化混沌測試實踐

TesterHome小助手發表於2024-04-23
  • 綜合編譯|TesterHome 社群
  • 作者|Joaquim Verges
  • 來源|Twitch Engineering

本文為亞馬遜旗下流媒體平臺 Twitch 工程師 Joaquim Verges 的技術經驗總結分享,供大家參考。

以下為作者觀點:

作為前端開發人員,我們並不經常聽說混沌測試(注:作者當時的語境)。一個與 Twitch 前端可用性相關的專案,讓我們開始研究由 Netflix 首創的令人興奮的混沌工程領域。

混沌工程(Chaos engineering)是一門透過模擬故障並測量這些故障對系統的影響來最佳化軟體系統彈性的科學。這些模擬有助於在實際問題發生之前對其進行預測,並確保我們的系統能夠正常降級。這種做法通常用於後端和分散式系統,並且該領域正在開發越來越多的工具。

然而,在前端,我們還沒有觀察到來自網路或移動社群的太多討論或活動,以確保我們的客戶具有應有的彈性。

我們的最終目標是能夠回答這個問題:“如果我們整個系統的這一部分(例如後端服務、第三方 API)出現故障,我們的前端會如何表現以及我們的終端使用者會看到什麼?”

模擬系統故障

在 Twitch,我們的資料由不斷增長的相互依賴的微服務集合(在撰寫本文時有數百個)提供服務。這些服務透過單個 GraphQL API 從我們的前端客戶端(網站、移動應用程式、控制檯應用程式、桌面)中抽象出來。

在像我們這樣的系統中發生的最常見的故障是我們的微服務錯誤之一併且無法提供其部分資料。在這種情況下,如果配置正確,GraphQL 可以很好地將部分資料轉發到客戶端。從那裡開始,客戶端的工作就是處理這部分資料並提供儘可能最佳的降級體驗。

考慮到這個常見的用例,我們的目標是找到一種可擴充套件的方法來測試這些場景並觀察每個客戶端的行為。

讓混沌工程開始吧!首先,我們需要一種可靠地模擬故障的方法。

第一個考慮的選項是攔截並更改收到的網路響應。混沌攔截器(chaos interceptor)將新增在 GraphQL 響應中注入錯誤的能力。這些錯誤可以是預先確定的,也可以是隨機注入的。


在探索此選項時,我們意識到,由於絕大多數 API 呼叫都透過 GraphQL,因此我們可能會透過 GraphQL 呼叫傳遞特殊指令,以模擬 GraphQL 解析器端的某些故障。幸運的是,事實證明這一功能已經在我們的一個駭客週期間實現,並恰當地命名為 “混沌模式”。

混沌模式新增了向我們的暫存 GraphQL 呼叫傳遞額外標頭的功能。在該標頭中,我們可以傳遞我們希望模擬故障的一個或多個服務的名稱。我們的臨時 GraphQL 解析器讀取此標頭並短路對這些服務的任何內部呼叫。


自動混沌測試

一旦我們找到了模擬故障的方法,下一步就是使該過程自動化。在 Twitch,我們大量使用自動化來測試我們的前端使用者流程。這些指令碼化測試,可以模擬使用者操作我們的網站或應用程式,驗證一切是否按預期顯示。

我們意識到,透過使用特殊的混沌模式標頭集執行我們的核心測試,可以非常容易地實現故障模擬自動化。這種設定可以告訴我們特定的服務故障是否會破壞這些核心流程,這已經非常接近我們的目標了!

在 Android 上執行快速原型後,我們發現缺少一些東西來使其可擴充套件:

  1. 由於功能和服務會隨著時間的推移而變化,因此我們的測試套件需要一種方法來 “發現” 我們應該強制失敗的服務。手動對映不可維護且無法很好地擴充套件。

  2. 看到測試結果是一個很好的開始,但我們應該能夠從這些執行中提取更多有用的資訊。例如哪個服務導致了故障、哪些特定的 API 呼叫受到了影響,甚至還包括用於視覺化使用者體驗的故障螢幕截圖。

為了解決第一點,我們需要一種方法來 “跟蹤” 來自客戶端的 GraphQL 呼叫並記錄特定使用者流訪問了哪些內部服務。我們透過在 GraphQL 呼叫中使用另一個除錯標頭(debug header)解決了這個問題,該標頭支援在 GraphQL 解析器層進行跟蹤。然後,解析器記錄對其內部服務依賴項執行的任何方法呼叫,並在同一 GraphQL 呼叫中將資訊傳送回客戶端。從那裡,客戶端可以提取一組 GraphQL 呼叫中涉及的服務名稱,並將其用作混沌測試套件的輸入。

我們現在有一個兩步過程:

  1. 在啟用跟蹤的情況下執行端到端測試,並記錄每個測試涉及的所有服務。

  2. 使用此服務列表,我們可以透過強制每個服務一一失敗來執行混沌模式測試。

透過此設定,我們現在擁有一種自動方式來發現服務,然後強制它們以一致、可重現的方式失敗。然後我們可以將其擴充套件到任意數量的自動化測試。

儀表板和視覺化

有了這個系統,我們繼續提取並記錄有趣的資訊,這些資訊將描述這些強制故障期間的使用者體驗。

我們使用執行 n 次(每次服務故障一次)的單個使用者流(即導航到螢幕/頁面、觀看流、傳送聊天訊息等)的測試結果,並使用它們來計算彈性分數對於那個特定的測試。一個簡單的百分比數字,表示儘管持續出現服務故障,但使用者流成功的次數。然後為客戶計算全域性彈性分數,從而高度概述每個客戶對故障的敏感程度。

我們可以使用這些分數來跟蹤使用者流隨時間變化的彈性,衡量我們對程式碼所做的改進,並確保我們不會意外倒退。我們將這些分數和其他有用資訊打包並上傳到伺服器,以便我們可以在網路儀表板中將其視覺化。

在測試過程中,我們捕獲 API 呼叫,提取有用的資訊,例如哪個特定 GraphQL 有錯誤、該查詢中的哪個欄位導致了錯誤,並且我們還捕獲了預期狀態和錯誤狀態的螢幕截圖。所有這些資訊都有助於診斷給定故障下客戶端到底發生了什麼。

使用此儀表板,我們發現 Android 和 iOS 彈性分數之間存在很大差距。

Android 的總體得分為 82%,而 iOS 的得分僅為 64%。使用提供的除錯資訊,iOS 團隊確定了根本原因:對網路堆疊深處的 GraphQL 錯誤的過度防禦性處理。該團隊能夠透過重新執行自動化混沌測試來測試他們的修復,並驗證該修復顯著提高了彈性,將 iOS 彈性得分提高到 84%。

下一步

現在,我們每天晚上在 Android、iOS 和 Web 客戶端上執行這個工具。這使我們能夠深入瞭解當前前端對後端服務故障的恢復能力。我們現在可以跟蹤我們的彈性分數如何隨時間變化,並輕鬆測試過去難以測試的故障場景。

我們計劃透過在我們的自動化測試中新增更多超出核心流程的使用者流程來擴大覆蓋範圍。在系統中新增新測試就像為平臺編寫任何自動化測試一樣簡單,我們目前正在努力新增行動網路作為目標平臺之一。

我們還計劃改進混沌模式和跟蹤服務呼叫的能力,以解決當前的限制。最高優先順序是跟蹤和失敗輔助服務呼叫(服務到服務互動)的能力。我們正在考慮的其他功能是能夠使單個服務呼叫失敗以及同時使多個服務失敗。

混沌工程的學科可能是為後端分散式系統建立的,但感覺前端還有很多東西需要探索!令人驚奇的是,這些工具將來自不同領域的工程師聚集在一起,進行協作,並使他們能夠更深入地瞭解我們的系統端到端。(原文連結:https://blog.twitch.tv/en/2022/01/10/automated-chaos-testing-on-the-front-end/

相關文章