Go Wiki:測試失敗
如果您發現 Go 專案中的測試失敗,您應該怎麼做?
測試目標
撰寫(並執行)Go 套件測試的目標是了解該套件及其依賴項的行為。
Go 套件的測試失敗可能會提供以下資訊給我們:
- 套件或其依賴項中的實作缺陷、
- 對套件 API 的錯誤假設、
- 測試本身的缺陷(例如對時間安排的無效假設)、
- 出乎意料的資源需求過高(例如 RAM 或 CPU 時間)、或
- 底層平台中的錯誤或測試基礎結構的缺陷(可能需要升級或變通方法)。
某些情況下,測試失敗的原因可能不明確:這可能是由上述兩個以上條件所造成的。就像在科學實驗中重覆實驗一樣,允許測試多次失敗有時可以從特定的失敗模式提供更多資訊。
然而,如果測試失敗且未提供任何新資訊,表示該測試並未發揮其用途。
尋找測試失敗
測試故障通常會從下列管道發現
- 待處理變更上的 TryBot 或 SlowBot 故障;
- 在特定套件或套件上執行
go test
,可以在 Go 專案儲存庫內運作,或作為使用者模組中的 (例如)go test all
的一部分; - 或在 從來源安裝或 測試已貢獻的變更時執行
all.bash
或all.bat
。
測試故障分級
一旦我們發現故障,我們需要進行分級。分級的目標是識別
- 故障資訊是否為新資訊?
- 誰最適合分析故障中的新資訊?
識別新資訊
從 公開問題中搜尋故障中的關鍵細節開始,例如失敗測試的名稱和/或錯誤文字的其他獨特片段 (例如錯誤代碼)。
如果您找到現有問題,請先查看問題討論,以了解是否已修復故障以及您的故障資訊是否有提供相關新資訊。如果是,請就此提供意見,內容包含
- 說明您測試的 Go 版本 (
go version
) - 您執行測試的方式和位置,例如
go env
輸出- 您的機器和作業系統設定檔
- 您的網路設定檔和狀態
- 您能重現故障的頻率或方式。
理想情況下,請附上或連結至完整的測試記錄 (可能會放在 <details>
區塊中)。
如果您沒有找到現有問題,請建立一個新問題。
建立問題
貼上 足夠 的測試記錄,讓後續報告者能夠搜尋到這個問題,包括測試名稱及其記錄輸出的任何獨特部分。(如果是冗長的測試記錄—例如包含大量 goroutine 傾印—請考慮張貼較短的摘要和/或將完整的失敗訊息包裝在 <details>
區塊中。)
您可以使用 fetchlogs
和 greplogs
工具,在建置儀錶板中搜尋類似的故障
# download recent logs
fetchlogs -n 1024 -repo all
# search logs for some regexp describing the failure message
greplogs -l -e $FAILURE_REGEXP
如果故障看似特定於某個套件,請參閱 https://dev.golang.org/owners 以尋找該套件的維護人員,並在問題中提及他們。(如果未列出套件的任何維護人員,請在 https://cs.opensource.google/go 檢查套件的近期歷史記錄,或者升級到可以幫助識別相關維護人員的人員,並考慮用您所瞭解的來更新 維護人員表格!)
如果故障看似特定於 GOOS
或 GOARCH
標籤,請在問題中標註相對應的 GOOS 和/或 GOARCH 標籤,並在問題中提及 @golang/port-maintainers 的相關子團隊。
如果故障看似至少影響一個 第一類埠,請將問題新增到目前的發行里程碑並標註 release-blocker
。否則,將問題新增到 待處理
里程碑。
如果故障看似特定於組建模組(例如網路連線問題,或需要系統更新的平台錯誤),請參閱 x/build/dashboard/builders.go
以尋找該組建模組的維護人員,並在問題中提及他們。(對於未列出明確維護人員的組建模組,請改為提及 @golang/release 團隊。)
解決測試故障
針對測試故障提交問題後,相關套件、埠和/或組建模組維護人員應檢查從測試故障中收集到的資訊,並決定如何透過下列任一方法來 解決 該問題:
- 回復 被認為導致問題的程式碼或測試基礎設施所做的變更,
- 修復 (或套用解決方法來處理)導致故障的根本原因,
- 收集 更多資訊,方法是訂閱問題更新和/或執行更多測試,
- 報告 相依性、平台或測試基礎架構中的基礎缺陷,以及/或者
- 降低 故障的優先順序,方法是略過受影響平台上的故障(或將那些平台標記為損壞),然後將問題移到未來的里程碑或
待處理
里程碑,以及/或移除release-blocker
標籤。
當維護人員決定降低測試故障的優先順序時,他們會決定 測試的額外失敗不會提供有用的新資訊。在這個時候,測試不再履行其目的,維護人員應抑制故障,通常是透過呼叫 testenv.SkipFlaky
或 t.Skipf
。
略過測試故障
當我們新增一個呼叫至 testenv.SkipFlaky
時,我們的目標在於移除無法提供新資訊的失敗模式,同時盡可能地保留測試的價值。
-
如果觀察到的失敗只是一種測試的可能失敗模式,則僅針對該失敗模式略過測試。
- 例如,如果錯誤始終是特定錯誤,如
syscall.ECONNRESET
,請使用errors.Is
檢查該特定錯誤。
- 例如,如果錯誤始終是特定錯誤,如
-
如果認為失敗會影響特定
GOOS
和/或GOARCH
的所有版本,或無法識別受影響版本,請針對runtime.GOOS
和/或runtime.GOARCH
進行檢查,並僅略過受影響的平台。 -
如果失敗是因平台的特定版本錯誤所致,請根據
testenv.Builder
或GO_BUILDER_NAME
環境變數略過測試。(如果測試對外部 Go 使用者失敗,他們可以選擇升級至不受影響的平台版本 — 且他們可能應查看測試失敗以瞭解錯誤是否存在!)- 另請考慮新增另一個環境變數,讓使用者和協力廠商可以設定以確認錯誤並抑制失敗。
將建置元件或埠標示為異常
平台錯誤或核心套件(例如 os
、net
或 runtime
)中的錯誤可能會影響許多測試,導致無法略過失敗,或在編譯或連結期間顯示為失敗。如果發生此類錯誤,選項會更受限:如果我們無法回復變更、修正或解決根本原因,也不需收集更多資訊,我們只能透過將整個建置元件或平台標示為異常來降低失敗優先順序。
若要將建置元件標示為異常,請編輯其在 x/build/dashboard/builders.go
的組態,以新增 KnownIssue
欄位的議題;請注意,具已知議題的建置元件通常會在控制面板分類期間被略過。
針對 一等埠 的異常建置元件應該將其已知議題標示為 release-blocker
,並暫停決定修正建置元件或中斷支援受影響的平台版本。
如果次要埠的所有建置元件都異常,則埠本身可能會被視為異常。 討論 #53060 旨在解決如何處理異常次要埠問題。
本內容是 Go Wiki 的一部分。