- 專案負責人:shayba@google.com、ananthak@google.com、fsamuel@google.com
- 專案合作夥伴:borthakur@google.com、jasoncampbell@google.com、lite@google.com、ppi@google.com
- 領域:測試
問題陳述
Fuchsia 平台和產品開發人員對樹狀結構外系統測試的需求目前未能滿足,或者使用錯誤的工具,導致測試涵蓋率不足或測試品質不佳。
以 Fuchsia 為基礎的產品開發作業會在 Fuchsia 來源樹狀結構之外 (樹狀結構外或 OOT) 進行,因此非常仰賴未受限的系統測試,在平台的嚴格定義合約之外執行 Fuchsia 平台。這是因為平台元件大多不提供支援的方式,無法執行滿足產品測試需求的檢測作業。測試作者可以找到方法來克服這些限制,但這些解決方案會導致測試品質不佳。
如果 Fuchsia 平台的開發程序採用可規避平台合約的 OOT 測試,就會威脅 Fuchsia 的更新功能。
什麼是系統測試?
系統測試是針對已組裝完成的系統進行測試,以驗證系統是否符合特定需求。在實用測試金字塔中,系統測試可補足單元測試和整合測試,填補只有在觀察測試中的完整系統時才能解決的測試缺口。
系統測試有時也稱為:
端對端 (或 e2e) 測試,尤其是當系統測試範圍超出特定目標裝置,並納入透過網路介面連線的遠端伺服器,或控制主機時。
關鍵使用者歷程 (CUJ) 測試,尤其是當測試以模擬和自動化使用者輸入和輸出方式表示時,例如透過注入按鈕按下等輸入事件,並將 UI 狀態摘要或螢幕截圖與預期的測試結果進行比較。
此外,這些測試還可進一步進行檢測,產生額外的價值,如下所示:
效能測試:除了執行產品 CUJ,測試系統也會收集效能資訊,例如時間、追蹤、FPS 統計資料等。
壽命測試,在緊密迴圈中執行相同的 CUJ,並監控系統是否出現資源耗損 (RAM、句柄等) 或當機等壓力跡象。
此外,還有一整類系統測試會測試平台功能,並樹狀結構內開發。這些不在本文的涵蓋範圍。
目前在 Fuchsia 上遇到的系統測試挑戰
非密封的舊版 (v1) 元件測試
Fuchsia 的元件架構提供廣泛的測試支援,可在測試環境和系統的其他部分之間實現高度隔離。系統仍支援舊版 (CFv1) 測試,可用於測試尚未遷移至 CFv2 的舊版元件。雖然大多數的正式版元件仍為 CFv1,但大多數測試 (超過 70%) 都使用 CFv2 測試架構,因為後者更可靠,且可為開發人員提供一些新功能。
基於舊版原因,v1 測試執行階段在許多方面並未達到密封狀態,例如允許存取特定實際系統服務。因此,許多 CFv1 測試其實會意外地以系統測試的形式運作。這些測試會發生多項問題,包括:
由於測試範圍非常廣泛或未嚴格定義,因此很難排除測試失敗的問題。
測試可能會受到外部狀態的影響,或會將外部狀態留作副作用。因此,這些測試可能會與其他類似的系統測試產生交互作用,導致無法重現的失敗 (「片段」),或是在不穩定的情況下重現失敗,例如以不同順序重新執行相同的測試。
假設其他系統元件實作細節超出其規定合約的測試。
元件測試架構的設計目的,是用於編寫隔離的密封單元測試和整合測試。在這種測試中,任何失敗原因都只能來自測試領域內。由於預期會隔離測試,因此任何兩項測試都能同時執行或以任何順序執行,而不會影響結果。使用已淘汰的 CFv1 功能來破壞測試沙箱和寫入系統測試,會破壞這些保證,並導致難以排除的問題。許多上述測試的作者都不知道自己其實在進行系統測試。
違反 Fuchsia 系統介面的 OOT CUJ 測試
對於 OOT 軟體,與 Fuchsia 平台互動的預期方式和支援方式是透過 Fuchsia 系統介面 (FSI)。不過,目前有工具可供 OOT 開發人員使用,讓測試作者略過這個介面,並違反平台產品合約。
Fuchsia 的 Scripting Layer (SL4F) 是系統自動化架構,可用於編寫全面的系統測試。
SL4F 的靈感來自 Android 專用指令碼層 (SL4A)。這項功能原本是用於樹狀結構內的平台系統測試。特別是 SL4F 對於移植 Android Comms Test Suite (ACTS) 測試等項目非常實用,因為這些項目會使用相同的基礎 JSON-RPC/HTTPS 通訊協定來驅動目標裝置。這項安排對於 Fuchsia 連線測試非常實用。
作為系統自動化架構,SL4F 也可用於測試 CUJ。舉例來說,SL4F 可為平台 CUJ 測試提供動力。
不過,SL4F 並非用於 OOT 測試。與 SL4F 的互動是透過 FSI 以外的通訊協定完成,且不提供與 FIDL 相同的演進機制,例如您可以透過引入新的外觀,擴充 SL4F 的自動化功能,但所有外觀都必須樹狀結構內開發及建構。因此,如果要為定義及開發 OOT 的產品測試 CUJ,使用 SL4F 會導致下列部分問題。
另一種常見的機制是使用 SSH 取得遠端殼層,並在主機和目標之間複製檔案,以便進行過度侵入性的測試。請勿將這項功能與將 SSH 做為隧道通訊協定的用途混淆,因為這項用途可用於 Overnet 的傳輸。
目前的 Fuchsia 工程版本包含 SSH 守護程式,可在未受限的情況下存取全域命名空間,並為用戶端提供 dash
殼層。同一個守護程式也允許 SCP 功能,以類似程度的讀取/寫入權限存取全域命名空間,例如全域可變動儲存空間。這通常是繞過 FSI 的方法,讓測試作者能夠在可變化儲存空間中觀察或變更平台元件的狀態,並依此違反平台元件所支援的介面,這類操作會依賴 Fuchsia 基礎套件的名稱等平台實作詳細資料。
安全殼層和 SCP 存取權已連結,方便測試作者使用,例如在 Dart 中使用 SL4F 用戶端程式庫。
脆弱的測試模式
SL4F 提供許多方法,讓測試作者操控及觀察系統狀態。其中部分機制會略過平台產品合約和必要的抽象層。撰寫 SL4F 測試時,並非一定要使用這些機制,也不是所有測試都需要使用這些機制。但這些歡迎的存在會讓 SL4F 測試的商品目錄出現許多反模式。
值得注意的是,由於平台未提供可滿足測試需求的強大替代方案,因此我們才開發出這些模式。我們列出這些模式,並非為了批評平台開發人員或測試作者,而是為了瞭解並歸類目前我們必須償還的技術債務。
透過非合約觀察狀態
測試中的程式碼可能會將狀態資訊傳送至系統記錄,或透過「檢查」功能傳送。這些工具可用於收集診斷資訊,並將其儲存為快照。但這類內容並非合約。在 Fuchsia 上使用 FIDL 可定義強型別的契約,這些契約可保持穩定,並具備演進機制,例如對線路格式和版本控制進行二進位相容性變更,這可讓未協調的用戶端和伺服器交換 FIDL 訊息。FIDL 是專為這項用途而精心設計,而自由文字記錄和檢查並非如此。
一些值得注意的具體例子
測試中的記錄:部分耐久性測試會使用記錄,並在「錯誤」或更高嚴重性層級加上註解,以便在測試期間找出產品受到非預期壓力的情況。很抱歉,從測試作者的角度來看,在測試執行期間傳出的「錯誤」訊息通常是良性的。因此,長壽測試作者必然會維護記錄錯誤訊息的許可清單。
在測試中檢查:部分測試驅動程式會讀取檢查資訊,以便觀察所驅動元件的狀態。由於檢查工具是類型化資料,且可取得為單一一致的快照,因此對於元件作者而言,這是用於診斷元件目前狀態的實用工具。不過,如果將其用於平台元件和產品測試之間的契約,就會導致 ABI 不穩定,且經常導致中斷。這些中斷情形可能會在基礎平台變更後數週發生,因為 SDK 會在嘗試推出時發生中斷情形。
透過非合約操控狀態
SL4F 測試可對主機進行大量控管,包括在未隔離的殼層 (即全域命名空間) 中執行任意 SSH 指令,以及對全域不可變動和可變動的儲存空間擁有完整的讀/寫存取權。以下列舉幾個重要範例:
終止及重新啟動程序:這項操作通常用於測試中的設定和拆解例程。意圖是正面的 - 測試想要清除任何先前的狀態,並重新開始。不過,測試中的平台元件不一定經過測試,無法在多次或以不同順序重新啟動時保持穩定,這通常會導致不穩定的行為。
這種做法還有另一個問題,就是當 OOT 測試終止平台程序時,程序名稱 (不屬於平台合約的一部分) 會變成合約。這類違反預期介面和合約的情況會讓平台重構作業更加困難,並使 OOT 測試變得更加脆弱。
操控可變動儲存空間:這項明顯的沙箱違規行為通常用於將使用者憑證做為特定 CUJ 測試的設定步驟注入。系統不會操作預定的憑證插入介面,而是在測試中的程式碼讀取該狀態之前,先將狀態插入。如果時間不正確,測試就會失敗。如果清理作業失敗,後續測試可能會因受到測試交談的影響而失敗。
全球可變化檔案系統存取權的另一個用途,是將全球 /tmp
儲存空間目錄用作測試結果、構件和診斷資訊的暫存區,例如在測試期間收集到的效能追蹤記錄。這也是測試無法清除狀態、透過交談影響彼此,或以其他方式注入不實或不穩定行為的機會。
不同元件執行個體的隔離儲存空間目錄會在同一個分區中管理,因為為不同元件建立個別分區的成本高昂且缺乏彈性。您可以在共用分區上建立特定目錄版面配置,藉此實現隔離。目錄版面配置會反映平台實作細節,例如元件拓撲或元件管理服務將該拓樸轉譯為檔案系統部分的方式。再次強調,這些是平台實作細節,可能會隨時間變更,且不應公開給 OOT 測試。
結果
在同一項測試中混合開放式測試和封閉式測試,會導致品質不佳的測試,因為這類測試會設定不相關的預期值,並以測試中的軟體未設計支援的方式,協調及觀察狀態。
目前的情況是因為系統測試工具長期未受到重視,而導致 Fuchsia 平台提供的服務。不過,我們發現許多特殊測試不符合現有類別,且違反測試最佳做法。
更糟的是,這些測試所依賴的平台實作詳細資料,其表達方式並非為了讓測試能夠持續演進而設計。舉例來說,許多 FSI 都是以 FIDL 的形式精確定義。FIDL 的設計目的是讓平台開發人員能夠進行與 ABI 相容的變更,或偵測現有 ABI 何時因特定變更而中斷。FIDL 提供多種方式,讓開發人員在不破壞 ABI 的情況下變更類型和通訊協定,或以受控方式引入破壞:穩定的通訊協定方法序號、彈性表格、版本控制等。
請比較這項功能與使用程序名稱做為合約的情況,例如為了讓測試終止程序。由平台元件實作的程序名稱絕不會是 FSI 的一部分,部分原因在於沒有進化功能 - 任何變更都是重大變更,沒有版本功能,而且很少有同時執行舊程序和新程序的情況,以便暫時相容。同樣適用於全域檔案系統路徑、內部檔案格式、自由文字記錄檔和其他類似的非合約內容。
缺少 OOT 支援
SL4F 用戶端可以透過與 SL4F 守護程序對話,將系統自動化,該守護程序包含在平台映像檔中,並透過 Fuchsia SDK 發布給 OOT 測試人員。這個系統的這項功能通常運作良好,因為它是穩定的合約,且有合理的方式可隨著時間演進。
不過,您只能樹狀結構內開發外觀,也就是說,目前無法在 OOT 中擴充系統自動化功能。這並非 SL4F 的意外屬性,因為 SL4F 根本就不是由 OOT 用戶端使用。
分開堆疊
SL4F 提供設定、裝置探索、主機-目標網路傳輸通訊協定、一些可擴充性機制,以及向 SDK 客戶提供用戶端程式庫和工具的方式。
ffx
也解決了相同的問題,而且方法可能更佳。開發 ffx
外掛程式時,如果主機端外掛程式需要目標端協同合作元件來掌控目標,則可以開發 FIDL 代理程式。主機和目標之間的通訊會以 FIDL 定義,與 HTTP 上的 JSON-RPC 不同,FIDL 可成為 FSI 的一部分,並可與其他平台和 SDK 的契約一起發展。這在某種程度上是因為使用 FIDL 維持 ABI 相容性比使用結構定義僅存在於程式碼中的無型別 JSON 合約更容易。
相關地,ffx
堆疊可以更深入瞭解 Fuchsia 元件,例如瞭解何時以及如何啟動測試所需的元件。它也解決了 SL4F 堆疊未處理的問題,例如主機-目標驗證。這可讓您在 userdebug
建構類型中使用 ffx
,而 SL4F 則僅可在 eng
建構中使用。
其他自訂測試裝置
上述未列出的其他測試解決方案,這些測試涵蓋了整個測試範圍,但由於未使用平台本身的隔離機制進行測試,因此大多會以系統測試的形式進行協調。
部分 OOT 合作夥伴會共用部分測試解決方案和工具,但不一致。因此導致技術債增加。
解決方案陳述式
Fuchsia 平台團隊將在樹狀結構和 OOT 中建立完善的系統測試解決方案。平台團隊會與產品團隊合作,瞭解產品測試需求並滿足需求,並協助產品團隊進行任何遷移作業。
新解決方案將採用 Component Framework 和 ffx
外掛程式的沙箱功能,以便:
- 讓您能夠編寫優質的 OOT 測試,包括優質的系統測試。
- 讓編寫違反 Fuchsia 平台嚴格定義且支援的合約的 OOT 測試變得更困難 (幾乎不可能)。
具體違規事項如下:
在適用情況下,推廣元件化單元和整合測試
如果 OOT 測試可重新實作為在測試領域中執行的元件,以產生密封的單元測試或整合測試,我們會以這種方式重新實作。為了啟用並推廣更健康的測試金字塔,我們將提供與樹狀結構內元件測試相同的 OOT 元件測試支援。
重新實作所有非密封的 CFv1 測試
所有現有的舊版 CFv1 測試,如果會透過存取實際的系統服務而違反密封性,將會以其他方式重新實作,以滿足相同或更嚴格的測試規定。這些測試是否要重新實作為密封的 CFv2 元件測試、新系統測試或其他形式,則由測試程式碼的擁有者決定。
如果平台測試支援功能缺少或不足,例如 CFv1 元件擁有者無法遷移至 CFv2,相關平台團隊將與測試擁有者合作,建立必要的平台解決方案。
為產品擁有者建立新的系統測試平台解決方案
Fuchsia 平台團隊將開發新的解決方案,以便您編寫符合下列條件的系統測試:
系統測試可在 OOT 中開發及執行。
無論是在本機開發人員工作流程中執行測試,且不考慮開發人員環境為何,或是在某些 CI/CQ 自動化作業中執行相同測試,且不考慮使用的自動化解決方案為何,您都可以透過同一種方式叫用這些測試並收集結果,確保遵循相同的工作流程,並在所有地方取得相同一致的結果。
平台的詳細資料如果不是預期合約的一部分,例如 Fuchsia 系統介面中定義的內容,就不會公開給 OOT 系統測試開發人員。為啟用所需的沙箱層級,系統會將測試和測試架構遷移至 CFv2 (如果尚未遷移)。
系統測試架構會與
ffx
共用相關的堆疊。這包括設定、主機工具和用戶端程式庫發布機制、版本、設定、目標裝置探索、主機-目標驗證、主機-目標傳輸,以及用於遠端控制的機制。平台系統元件的擁有者可以,也將會擴充系統測試架構,以滿足產品開發人員的測試需求。如此一來,平台開發人員就能建立可維護的 ABI,並建立這些可測試性合約的長期擁有權。
減少並淘汰舊版解決方案
平台和產品團隊將攜手合作,停止使用先前的解決方案,並在所有地方採用新的系統測試架構。除非有特殊誘因,否則舊版測試解決方案不會長期使用,例如在需要跨平台測試套件相容性的情況下。
優先順序
相關團隊可視需要調整工作優先順序。不過,我們建議您先將工作排序,然後解開最耗費人力和維護成本的測試,例如先解決技術債曲線的起點。
無論選擇哪項工作,在考量可採取哪些行動來償還技術債務時,系統測試的現代化工作都會被視為優先任務。
依附元件
為了彌補平台可測試性差距,並開發及推出新架構,我們需要跨多個平台團隊合作,包括元件架構、測試架構、SDK 工具、EngProd 測試和 EngProd 基礎架構。
此外,所有產品合作夥伴團隊和多位平台元件擁有者都必須投入工作,協助找出可測試性差距,並將測試作業遷移至新的測試架構和解決方案。
風險與緩解措施
系統測試的範圍並非特定元件或套件,而是整個測試系統。因此,系統並未嚴格定義實際測試的程式碼。從任何一個架構將系統測試遷移至另一個架構時,可能會失去一些系統測試的附帶好處,也就是測試涵蓋率。
有些系統測試的範圍非常廣泛,因此對重新實作作業設下了非常高的門檻。這是一個實用的預先因素步驟,因此縮小或分割部分測試可能會有所幫助。
部分現有系統測試沒有專屬的長期負責人。這類廢棄軟體的使用難度較高,因此某些遷移工作勢必會落在其他人身上。
如要配合新式解決方案,尤其是 OOT,就必須處理 OOT 和產品端 CFv2 遷移作業。CFv2 遷移作業進展順利,但目前仍以系統元件為主,OOT 或產品端元件的遷移作業尚未開始。因此,您可以合理地預期會出現不明的阻擋項目。
技術債務一向與其他團隊優先事項競爭。領導階層必須達成共識,才能有效執行這項轉移作業。
不在範圍內
樹狀結構中的系統測試
本文不涵蓋樹狀結構內開發的測試。雖然上述工作可能會帶來意外收穫,有利於樹狀結構內系統測試,但樹狀測試的問題陳述與樹狀測試的差異相當大,因此我們在此不討論這項問題。舉例來說,樹狀結構內的測試可以在 Fuchsia 平台介面下運作,不會影響 Fuchsia 的可更新性原則和目標。
元件測試
如要瞭解元件測試 (也就是以一組一或多個元件表示的測試,用於實作單元測試或整合測試),請參閱樹狀結構外元件測試支援的路線圖文件。
特殊移植需求
在某些特殊情況下,您需要在 Fuchsia 上執行現有的測試套件,以證明與其他實作相容或符合規定,或用於基準測試。在這種情況下,您必須執行未經修改的先前測試,否則無法確實證明相容性。這反過來說,為裝置端測試自動化系統定義規格。
解決這個問題的常見方法是將先前測試架構移植到 Fuchsia。舉例來說,Fuchsia LLVM Toolchain 和 Fuchsia Rust Toolchain 團隊正計劃分別移植 LLVM 和 Rust 測試架構,以便在 Fuchsia 上執行上游測試。這項做法的好處是,可將 Fuchsia 升級為更高層級的工具鍊支援,分別適用於這些外部專案。
另一個常見的解決方案是根據相同規格重新實作測試架構。舉例來說,Fuchsia 連線團隊將 SL4F 實作為 SL4A 的 JSON-RPC/HTTPS 規格,以便在 Fuchsia 上執行 ACTS 測試。這項功能的好處是為 Fuchsia 帶來大量實用的測試,並展示連線領域中至關重要的相容性。
只要以正確的理由和嚴謹的方式使用,這些都是解決這個獨特問題空間的絕佳方法。舉例來說,如果我們將 LLVM 測試架構移植至 Fuchsia,然後使用這個架構編寫新的測試,但這些測試超出與合作夥伴專案示範相容性或共用測試的範圍,就需要額外說明理由,否則平台團隊會不鼓勵這類行為。