提振精神
軟體測試是常見做法,可協助團隊持續交付高品質程式碼。測試軟體行為的不變量、偵測並防止功能或其他所需屬性發生回歸,以及協助擴展工程程序。
以原始碼行涵蓋範圍來評估測試涵蓋範圍,有助於工程師找出測試解決方案的缺口。將測試涵蓋率做為指標,有助於提升軟體品質,並促進更安全的開發做法。持續評估測試涵蓋範圍,有助於工程師維持高品質。
測試涵蓋範圍無法保證程式碼沒有錯誤。測試應搭配其他工具使用,例如模糊測試、靜態和動態分析等。
絕對測試涵蓋範圍
絕對測試涵蓋範圍是指完整測試集涵蓋的所有來源程式碼行數。Fuchsia 的持續整合 (CI) 基礎架構會產生絕對涵蓋率報表,並持續更新。涵蓋範圍報表通常最多只會延遲幾小時。
絕對涵蓋範圍資訊主頁
如需最新絕對涵蓋率報告,請參閱這篇文章。 這個資訊主頁會以樹狀結構顯示所有測試涵蓋的程式碼,做為來源樹狀結構的子集。您可以依目錄結構瀏覽樹狀結構,並查看目錄的涵蓋範圍總指標,或檔案的個別行涵蓋範圍資訊。
此外,Google 內部程式碼搜尋功能也提供涵蓋範圍資訊做為圖層。

測試涵蓋率增幅
Gerrit 程式碼審查網頁版 UI 會顯示變更的增量測試涵蓋範圍。增量涵蓋範圍會顯示特定變更的測試涵蓋哪些修改過的程式碼行,以及哪些修改過的程式碼行未涵蓋。
Fuchsia 的 Commit Queue (CQ) 基礎架構會收集增量測試涵蓋範圍。將變更傳送至 CQ (Commit-Queue+1) 時,您可以按一下「Checks」分頁標籤,然後依序點選三點選單下方的「Show Additional Results」,接著在篩選文字方塊中輸入「fuchsia-coverage」,找出負責收集增量涵蓋範圍的 tryjob,以便在 Gerrit 中顯示。這個 tryjob 完成後,修補程式集應具有絕對涵蓋範圍 (|Cov.|) 和增量涵蓋範圍 (ΔCov.)
針對影響專案的變更,持續維持高增量測試涵蓋範圍,有助於持續維持高測試涵蓋範圍。特別是防止在專案中導入未經測試的新程式碼。變更作者可以查看變更的增量涵蓋範圍資訊,確保測試涵蓋範圍足夠。程式碼審查人員可以查看變更的增量測試涵蓋範圍資訊,並要求作者填補他們認為重要的測試缺口。


以涵蓋範圍為導向的開發工作流程
您可以在瀏覽器或 VS Code 中,查看 Fuchsia 元件測試和主機測試的本機編輯涵蓋範圍。您可以使用這項功能建立以涵蓋範圍為導向的開發工作流程。
準備測試環境
首先,請設定建構作業,使用涵蓋範圍變數。請注意,--variant coverage只會檢測 Fuchsia 目標二進位檔 (host = false)。如要收集主機測試的涵蓋範圍,請使用 --variant host_coverage。
Fuchsia 元件測試
fx set core.x64 --variant coverage --with examples/hello_world
fx build主機測試
fx set core.x64 --variant host_coverage --with examples/hello_world
fx build首先啟動模擬器 (即目標裝置),然後啟動更新伺服器。這個步驟會用到兩個終端機。如果您已執行目標裝置 (模擬器或實體硬體),可以略過這個步驟。
在第一個終端機中:
fx qemu -kN接著,啟動套件伺服器,用來將更新發布至測試套件,這個程序會在背景執行。如果已執行套件伺服器,可以略過這個步驟。
在第二個終端機中:
fx serve在瀏覽器中查看涵蓋範圍
在這個工作流程中,我們會執行測試並產生涵蓋範圍報表,以便在瀏覽器中查看。
執行測試並匯出涵蓋範圍 HTML 報表
我們會執行測試並產生 HTML 報表。
C++
fx coverage --html-output-dir $HOME/fx_coverage hello-world-cpp-unittests荒漠油廠
fx coverage --html-output-dir $HOME/fx_coverage hello-world-rust-tests在瀏覽器中查看涵蓋範圍摘要
使用瀏覽器開啟 $HOME/fx_coverage/index.html。畫面上應會顯示涵蓋範圍摘要頁面。

按一下任一檔案,即可查看該檔案的行涵蓋率。「Count」欄會顯示測試期間的行造訪次數,至少為 1 次。「Count」值為空表示 0,也就是該行未涵蓋。
在 VS Code 中查看涵蓋範圍
請先準備測試環境,再開始執行本節內容。
- 從 Visual Studio Marketplace 安裝 coverage-gutters 擴充功能。
- 將下列屬性新增至
settings.json,即可設定涵蓋範圍間距。
{
"coverage-gutters.coverageBaseDir": ".",
"coverage-gutters.showLineCoverage": true,
"coverage-gutters.coverageFileNames": ["lcov.info"]
}
執行測試並查看涵蓋範圍
讓我們執行測試並匯出 LCOV 檔案,VS Code 會使用該檔案顯示涵蓋範圍。
C++
fx coverage --lcov-output-path $FUCHSIA_DIR/lcov.info hello-world-cpp-unittests荒漠油廠
fx coverage --lcov-output-path $FUCHSIA_DIR/lcov.info hello-world-rust-tests在 VS Code 中查看涵蓋範圍
- 找出要查看涵蓋範圍的檔案。
- 在檔案的編輯區域上按一下滑鼠右鍵,然後選取「Coverage Gutters: Display Coverage」(涵蓋範圍溝槽:顯示涵蓋範圍)。
- 綠色代表涵蓋的路線,紅色代表未涵蓋的路線。
- 您可以重新匯出 LCOV,然後重做步驟 2,查看更新後的涵蓋範圍 (由於某些原因,「watch」無法運作)。


針對變更重新執行測試
最後,您可以使用這項指令監控檔案系統變更,並在每次儲存程式碼時重新執行測試。
C++
fx -i coverage --lcov-output-path $FUCHSIA_DIR/lcov.info hello-world-cpp-unittests荒漠油廠
fx -i coverage --lcov-output-path $FUCHSIA_DIR/lcov.info hello-world-rust-tests排除端對端 (E2E) 測試
只有單元測試和密封整合測試,才可視為測試涵蓋範圍的可靠來源。系統不會收集或顯示端對端測試的測試涵蓋範圍。
端對端測試是大型系統測試,會全面測試產品,不一定涵蓋明確定義的原始碼部分。舉例來說,Fuchsia 上的 E2E 測試通常會在模擬器中啟動系統、與系統互動,並預期特定行為。
原因
因為端對端測試會全面檢測系統:
- 據觀察,這些測試經常會在執行期間觸發不同的程式碼路徑,導致涵蓋範圍結果不穩定。
- 這些要求經常在涵蓋範圍建構工具上逾時,導致建構工具不穩定。E2E 測試的執行速度比單元測試和小型整合測試慢得多,通常需要幾分鐘才能完成。由於涵蓋範圍負擔會降低效能,因此在涵蓋範圍建構工具上執行時,速度會更慢。
方式
對於 core 等頂層 buildbot 組合,系統會提供對應的 core_no_e2e,因此收集涵蓋範圍的機器人可以使用 no_e2e 組合,避免建構及執行任何 E2E 測試。
目前沒有可靠的方法可識別樹狀結構內的所有 E2E 測試。做為 Proxy,no_e2e 套件會透過 GN 的 assert_no_deps,確保遞迴依附元件中沒有任何已知的端對端測試程式庫。E2E 測試程式庫清單是手動管理及維護,並假設變更頻率極低:
e2e_test_libs = [
"//sdk/testing/sl4f/client",
"//third_party/mobly($host_toolchain)",
"//src/testing/end_to_end/antlion($host_toolchain)",
"//src/testing/end_to_end/honeydew($host_toolchain)",
]
# For libraries only supported on Linux hosts, we must use host_os to determine
# whether to include them. The is_linux condition will not function as naively
# expected because it applies to the current toolchain which may not be a host
# toolchain when this file is loaded.
if (host_os == "linux") {
e2e_test_libs += [ "//tools/emulator($host_toolchain)" ]
}
限制
目前,只有在下列情況下,系統才會收集測試涵蓋範圍:
- 程式碼是以 C、C++ 或 Rust 編寫。
- 程式碼會在 Fuchsia 的使用者模式下執行,或在主機上執行。目前不支援核心涵蓋範圍 (追蹤錯誤)。
- 測試會在 qemu 上執行。目前尚不支援在硬體上進行測試。
- 這項測試會做為
core產品設定的一部分執行。 - 系統不支援端對端 (e2e) 測試。
最後一點,端對端測試會在整個系統中執行大量程式碼,但執行方式在不同執行階段之間不一致 (或「不穩定」)。如要提高程式碼的測試涵蓋範圍,建議使用單元測試和整合測試。
實驗功能
根據預設,系統只會在 core.x64 中收集增量涵蓋範圍。如要收集 core.x64 和 core.arm64 中變更的合併涵蓋範圍,請按照下列步驟操作:
- 在 Gerrit 中,前往「檢查」分頁。
- 按下「選擇試用工作」。
- 新增
fuchsia-coverage-x64-arm64。

畫面會顯示勾號,狀態從「待處理」變成「完成」後,請重新整理 Gerrit,即可查看涵蓋範圍結果。
另請參閱: Issue 91893: Incremental coverage in Gerrit only collected for x64
即將推出的新功能
我們目前正在開發下列其他用途的支援功能:
- 核心程式碼涵蓋率。
- 涵蓋
core以外的產品設定,例如bringup或workstation_eng。 - 硬體目標的涵蓋範圍,也就是從未在 qemu 上執行的測試收集資料。
疑難排解
不支援的設定 / 語言 / 執行階段
如果程式碼沒有顯示絕對或增量涵蓋範圍資訊,請先查看限制,並確認程式碼是否應獲得涵蓋範圍支援。
為協助您排解問題,請檢查您是否缺少涵蓋範圍 (程式碼行應有涵蓋範圍,但顯示為未涵蓋),或完全沒有涵蓋範圍資訊 (檔案完全未顯示在涵蓋範圍報表中,或程式碼行未註解是否涵蓋)。
缺少涵蓋範圍表示程式碼是透過檢測設備建構,但實際執行的測試並未涵蓋該程式碼。如果完全沒有涵蓋範圍資訊,可能表示您的程式碼未建構涵蓋範圍,或測試未在涵蓋範圍下執行 (詳情請見下文)。
過時的報表 / 延遲
程式碼合併後,系統會產生絕對涵蓋率報表,但可能需要幾小時才能完整編譯。資訊主頁會顯示所產生報表的修訂版本雜湊。如果資訊主頁未顯示預期結果,請確認資料是在最近影響涵蓋範圍的變更後產生。如果資料顯示過時,請稍後再試,並重新整理頁面。
CQ 會產生涵蓋率增量報表。請確認您查看的是傳送至 CQ 的修補程式集。您可以點選「show experimental tryjobs」來顯示名為 fuchsia-coverage 的 tryjob。如果 tryjob 仍在執行,請稍後再返回並重新整理頁面。
確認測試已執行
如果程式碼缺少您預期會看到的涵蓋範圍,請選擇應涵蓋程式碼的測試,並確保該測試已在涵蓋範圍 tryjob 中執行。
- 在 Gerrit 中找出 tryjob,或在 CI 資訊主頁上找出最近執行的
fuchsia-coverage。 - 在「總覽」分頁中,找出「收集建構版本」步驟並展開,即可找到不同設定的涵蓋範圍建構版本和測試執行作業頁面連結。
- 這些頁面都應顯示「測試結果」分頁,其中會列出所有執行的測試。確認您預期的測試已執行,最好是已通過測試。
如果測試未如預期在任何涵蓋範圍試用作業中執行,原因可能只是測試僅在 CI/CQ 目前未涵蓋的設定中執行。另一種情況是,測試在涵蓋範圍變體中明確停用。舉例來說,參照測試的 BUILD.gn 檔案可能如下所示:
fuchsia_test_package("foo_test") {
test_components = [ ":test" ]
deps = [ ":foo" ]
# TODO(https://fxbug.dev/42074368): This test is intentionally disabled on coverage.
if (is_coverage) {
test_specs = {
environments = [
{
dimensions = emu_env.dimensions
tags = [ "disabled" ]
},
]
}
}
}
查看涵蓋範圍,找出測試遭停用的原因並進行調查。
如要瞭解如何排解測試未顯示涵蓋範圍的問題,請參閱這篇文章。舉例來說,如果測試未設為在 CQ 上執行,就不會顯示涵蓋範圍。
測試只會在涵蓋範圍內失敗或不穩定
如上所述,測試在涵蓋範圍 < 0x0A>example 下更容易發生問題。在執行階段收集涵蓋範圍會增加額外負荷,導致效能變慢,進而影響時間安排,這通常是造成額外不穩定性的原因。
另一個原因可能是測試期間發生逾時,但一般測試執行時不會遇到這種情況。實驗結果顯示,由於收集執行階段設定檔的額外負荷,涵蓋範圍變體中的測試平均會慢 2.3 倍。為此,執行涵蓋範圍建構作業時,測試執行元件會為每項測試提供較長的逾時時間。不過,測試可能仍有內部作業的專屬逾時,這可能會受到影響。
一般來說,測試不應發生逾時情況。在測試中等待非同步作業時,最好無限期等待,並讓測試執行元件的整體逾時時間到期。
最後,在涵蓋範圍變體元件中,可能會使用 fuchsia.debug.DebugData 通訊協定。這會干擾測試,因為測試會假設元件使用的功能。舉例來說:
如要立即修正,請在涵蓋範圍內停用測試 (請參閱上方的 GN 片段),但這樣一來,您就無法從測試中收集涵蓋範圍資訊。最佳做法是將涵蓋範圍的隨機失敗視為其他地方的隨機失敗,並修正隨機失敗問題。
另請參閱:不穩定測試政策。
Gerrit 中未顯示預期涵蓋範圍
如果您認為某些程式碼行應涵蓋在執行的測試中,但系統未顯示這些程式碼行的涵蓋範圍,請嘗試再次收集涵蓋範圍,方法是按下「Choose Tryjobs」,找到 fuchsia-coverage 並新增。

如果 fuchsia-coverage 完成 (變成綠色),但您看到不同的程式碼涵蓋範圍結果,則表示下列其中一項為真:
- 測試在不同執行階段,會以不一致的方式執行受測程式碼。這通常也會導致不穩定測試結果,而且通常是測試行為或受測程式碼的問題。
- 產生及收集涵蓋範圍資料時發生問題,導致結果不一致。請回報錯誤。
測試涵蓋範圍的運作方式
Fuchsia 的程式碼涵蓋率建構、測試執行階段支援和處理工具,都使用 LLVM 來源程式碼涵蓋率。編譯器 rt 設定檔執行階段支援 Fuchsia 平台。
選取 "coverage" 建構變化版本時,系統會啟用設定檔檢測。編譯器接著會產生計數器,每個計數器都對應至程式碼控制流程中的分支,並發出分支項目指令來遞增相關聯的計數器。此外,設定檔檢測插樁執行階段程式庫會連結至可執行檔。
如需更多實作詳細資料,請參閱「LLVM 程式碼涵蓋率對應格式」。
請注意,插樁會導致二進位檔大小增加、記憶體用量增加,以及測試執行時間變慢。為抵銷這項影響,我們採取了下列措施:
- 設定檔變數中的測試可享有較長的逾時時間。
- 系統會彙整商家檔案變化版本的測試結果,並提供一些最佳化建議。
- 目前涵蓋範圍以模擬器為主,儲存空間限制較少。
- 如果是涵蓋範圍增量,則只會檢測受變更影響的來源。
Fuchsia 上的設定檔執行階段程式庫會將設定檔資料儲存在 VMO 中,並使用 fuchsia.debug.DebugData 通訊協定發布 VMO 的控制代碼。這個通訊協定會在執行階段透過 元件架構 提供給測試,並由 Test Runner Framework 的裝置端控制器 (Test Manager) 代管。
測試領域終止後,系統會收集設定檔,以及其中託管的任何元件。接著,系統會將這些設定檔處理成單一測試摘要。這項重要最佳化措施可大幅縮減設定檔總大小。接著,最佳化設定檔會傳送至主機端測試控制器。
主機使用 covargs 工具 (該工具本身使用 llvm-profdata 和 llvm-cov 工具),將原始設定檔轉換為摘要格式,並產生測試涵蓋範圍報告。此外,covargs 會將資料轉換為 protobuf 格式,做為與各種資訊主頁的交換格式。
發展藍圖
持續進行的工作:
- 改善涵蓋範圍執行階段的效能和可靠性。
- 核心支援 ZBI 測試的程式碼涵蓋率。
- 自訂涵蓋範圍資訊主頁和快訊:為團隊建立資訊主頁。
- 本機工作流程:在本機執行測試,並在本機產生涵蓋率報告。
- IDE 整合:在 VS Code 中查看涵蓋範圍層。
近期作業:
- 樹外支援:涵蓋範圍超出 Fuchsia CI/CQ。