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

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


以涵蓋範圍為導向的開發工作流程
您可以在瀏覽器或 VS Code 中查看本機編輯作業的涵蓋範圍。 您可以使用這項功能建立以涵蓋範圍為導向的開發工作流程。
準備測試環境
首先,請設定建構作業,使用涵蓋範圍變數,並納入用於示範工作流程的範例。
C++
fx set core.x64 --variant coverage --with examples/hello_world --include-clippy=false
fx build荒漠油廠
fx set core.x64 --variant coverage-rust --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。您應該會看到涵蓋範圍摘要頁面。

按一下任一檔案,即可查看該檔案的行涵蓋率。「計數」欄會顯示測試期間的行造訪次數,至少為 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 測試通常會在模擬器中啟動系統、與系統互動,並預期會出現特定行為。
原因
因為端對端測試會全面測試系統:
- 據觀察,這些測試經常在執行期間觸發不同的程式碼路徑,導致涵蓋範圍結果不穩定。
- 這類要求經常在涵蓋範圍建構工具上逾時,導致建構工具不穩定。端對端測試的執行速度遠慢於單元測試和小型整合測試,通常需要幾分鐘才能完成。由於涵蓋範圍的額外負荷會降低效能,因此在涵蓋範圍建構工具上執行時,速度會更慢。
方式
對於 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 來源程式碼涵蓋率。編譯器執行階段設定檔支援 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。