•
Rust 程式碼覆蓋率工具大比拼:cargo llvm-cov 與 cargo-tarpaulin
12 分鐘閱讀 •
cargo llvm-cov
和 cargo-tarpaulin
都是 Rust 社群中用於衡量程式碼覆蓋率的重要工具。cargo llvm-cov
利用 LLVM 的原始碼級別覆蓋率工具,提供精確的行覆蓋率和區域覆蓋率,並且對程序化巨集(proc-macros)和文件測試(doc tests)有良好支援 1234。相較之下,cargo-tarpaulin
是一個歷史較久的工具,名稱源於覆蓋貨物的防水布,傳統上在 Linux x86_64 環境中運作良好,並致力於提供分支覆蓋等功能 56789。近年來,cargo-llvm-cov
因其報告的準確性和更現代化的底層技術而受到更多關注 10111213。
cargo llvm-cov
cargo llvm-cov
是一個 Cargo 子命令,它封裝了 rustc
編譯器的 -C instrument-coverage
選項,以便捷地使用 LLVM 的原始碼基礎程式碼覆蓋率功能 14151617。
特色
- 精準的覆蓋率數據:利用 LLVM 的能力,可以產生非常精確的覆蓋率報告,包括行覆蓋率和區域覆蓋率(region coverage)1234。區域覆蓋率能夠更細緻地顯示程式碼中特定區塊(例如
?
運算子導致的提早回傳)是否被執行 18。  - 廣泛的支援性:支援對一般的
cargo test
、cargo run
,以及程序化巨集(proc-macros)和文件測試(doc tests)進行覆蓋率收集 2319。它也能與cargo nextest
等測試執行器良好整合 19。 - 多種輸出格式:可以產生文字界面的總結報告,也能生成詳細的 HTML 報告以便於瀏覽 2021。同時支援 LCOV 格式輸出,方便與 VSCode 等編輯器的擴充功能(如 Coverage Gutters)整合 21。
- 跨平台潛力:由於基於 LLVM,理論上只要 LLVM 支援的平台,
cargo llvm-cov
就能運作,這使得它在 macOS 等非 Linux 環境下也能良好工作 222324。 - 安裝與使用:安裝通常透過
cargo install cargo-llvm-cov
和rustup component add llvm-tools-preview
完成 1821。自從 Rust 1.60.0 穩定化原始碼級別覆蓋率後,其使用變得更加便捷 18。
限制
cargo-tarpaulin
cargo-tarpaulin
是一個專為 Rust 專案設計的程式碼覆蓋率報告工具,其名稱取自一種用於覆蓋船上貨物的防水布 5725。
特色
- 穩定版 Rust 支援:
cargo-tarpaulin
可以在穩定的 Rust 工具鏈上運作 2627。 - 多種報告格式:能夠產生多種格式的報告,包括 HTML 和 LCOV,方便整合進 CI/CD 流程或與其他工具配合使用 2827。
- 歷史悠久:作為較早出現的 Rust 覆蓋率工具,擁有一定的社群基礎和使用案例 2930。
- 分支覆蓋嘗試:
cargo-tarpaulin
一直致力於提供分支和條件覆蓋的功能 8。
限制
- 平台依賴性:傳統上,
cargo-tarpaulin
主要支援 x86_64 架構的 Linux 系統,因其底層實現依賴於特定平台的除錯機制 69。 - 準確性疑慮:部分使用者回饋其覆蓋率報告的準確性相較於
cargo-llvm-cov
可能稍遜一籌 1213。 - 分支覆蓋率:與
cargo-llvm-cov
類似,在提供全面且穩定的分支覆蓋率方面仍有進步空間 1011。
主要區別比較
特性 | cargo llvm-cov | cargo-tarpaulin |
---|---|---|
底層技術 | LLVM 原始碼級別覆蓋率 (-C instrument-coverage ) 116 | 傳統上使用 ptrace/DWARF 除錯資訊,亦探索 LLVM 818 |
覆蓋精度 | 行覆蓋、區域覆蓋 (非常精確) 1218 | 行覆蓋,嘗試分支/條件覆蓋 8 |
Rust 版本 | 部分功能可能需 Nightly (但會自動安裝),Rust 1.60 後更易用 2618 | 穩定版 Rust 2627 |
平台支援 | 較廣 (基於 LLVM),macOS 支援良好 2224 | 傳統上主要為 Linux x86_64 69 |
報告準確性 | 通常被認為更準確 1213 | 可能略遜 1213 |
程序化巨集/文件測試 | 支援 2319 | - |
HTML 報告 | 支援,易於閱讀 2021 | 支援 28 |
分支覆蓋 | 有限支援 101121 | 有限支援,持續開發中 10118 |
近期趨勢 | 下載量和社群討論度較高 3121 | 較為老牌的選擇 529 |
如何選擇?
如果需要在 cargo llvm-cov
和 cargo-tarpaulin
之間選擇一個,可以考慮以下幾點:
追求最高的報告準確性和細緻度(如區域覆蓋):
需要在穩定版 Rust 上運作且對平台有特定限制(如僅限 Linux x86_64 且不願切換工具鏈):
需要更廣泛的平台支援(尤其是 macOS):
對程序化巨集和文件測試的覆蓋率有要求:
易用性和現代化整合:
總體建議
目前來看,對於大多數 Rust 專案,如果追求準確性、詳細的覆蓋資訊(包含區域覆蓋)以及更好的平台支援,cargo llvm-cov
會是更優先的選擇 12133118。儘管分支覆蓋率在兩個工具中都還不是完美狀態,但 cargo-llvm-cov
在其他方面的優勢使其更具吸引力。如果專案有嚴格限制必須在特定舊環境的穩定版 Rust 上使用 cargo-tarpaulin
且無法升級,則可繼續使用後者,但應了解其可能的限制。
我後來在 subx-cli 專案中採用 cargo llvm-cov
cargo-llvm-cov - crates.io: Rust Package Registry ↩ ↩2 ↩3 ↩4 ↩5
xd009642/tarpaulin: A code coverage tool for Rust projects ↩ ↩2 ↩3
今天才知道
cargo llvm-cov
和cargo nextest
: r/rust - Reddit ↩ ↩2 ↩3 ↩4 ↩5 ↩6TIL about
cargo llvm-cov
andcargo nextest
: r/rust - Reddit ↩ ↩2 ↩3 ↩4 ↩5 ↩6給cargo-llvm-cov 鼓掌- 真的超好用的覆蓋率報告: r/rust - Reddit ↩ ↩2 ↩3 ↩4 ↩5
给cargo-llvm-cov 点个赞- 真的很有用的覆盖率报告: r/rust - Reddit ↩ ↩2 ↩3 ↩4 ↩5
Rustの新しいコードカバレッジ/Source-based code coverage #テスト - Qiita ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10
[code coverage] cargo-llvm-cov vs tarpaulin #1195 - GitHub ↩ ↩2 ↩3
[code coverage] cargo-llvm-cov vs tarpaulin · Issue #1195 · rusqlite/rusqlite · GitHub ↩
[code coverage] cargo-llvm-cov vs tarpaulin #1195 - GitHub ↩ ↩2 ↩3
Current state of code coverage in Rust - help - The Rust Programming Language Forum ↩ ↩2 ↩3
How I can get coverage for cargo test? - Stack Overflow ↩ ↩2