#覆盖率 #cargo 子命令 #cargo #测试 #cargo-test #环境变量 #子命令

bin+lib cargo-llvm-cov

Cargo 子命令,用于轻松使用基于 LLVM 源代码的覆盖率(-C instrument-coverage)

96 个版本

0.6.11 2024 年 7 月 18 日
0.6.9 2024 年 4 月 5 日
0.6.8 2024 年 3 月 16 日
0.6.0 2023 年 12 月 28 日
0.1.0-alpha.22021 年 2 月 12 日

#2 in Cargo 插件

Download history 11077/week @ 2024-05-03 10473/week @ 2024-05-10 9452/week @ 2024-05-17 9421/week @ 2024-05-24 11384/week @ 2024-05-31 11654/week @ 2024-06-07 13291/week @ 2024-06-14 10903/week @ 2024-06-21 9547/week @ 2024-06-28 10421/week @ 2024-07-05 11245/week @ 2024-07-12 12750/week @ 2024-07-19 10533/week @ 2024-07-26 13377/week @ 2024-08-02 13219/week @ 2024-08-09 12230/week @ 2024-08-16

51,392 每月下载量
8 crates 中使用

Apache-2.0 OR MIT

215KB
4K SLoC

cargo-llvm-cov

crates.io license github actions

Cargo 子命令,用于轻松使用基于 LLVM 源代码的覆盖率。

这是一个对 rustc -C instrument-coverage 的包装,并提供

  • 生成非常精确的覆盖率数据。(行、区域和分支覆盖率。分支覆盖率目前是可选的,需要 nightly,见 #8 了解更多信息)
  • 支持与 cargo 兼容的命令行界面,包括 cargo testcargo runcargo nextest
  • 支持 proc-macro,包括 UI 测试的覆盖率。
  • 支持文档测试。(目前是可选的,需要 nightly,见 #2 了解更多信息)
  • 速度快,因为它没有在 rustc、cargo 和 llvm-tools 之间引入额外的层。

目录

用法

基本用法

点击以显示完整选项列表

请参阅文档目录以获取子命令的选项。

$ cargo llvm-cov --help
cargo-llvm-cov
Cargo subcommand to easily use LLVM source-based code coverage (-C instrument-coverage).

USAGE:
    cargo llvm-cov [SUBCOMMAND] [OPTIONS] [-- <args>...]

ARGS:
    <args>...
            Arguments for the test binary

OPTIONS:
        --json
            Export coverage data in "json" format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=text`. See
            <https://llvm.net.cn/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --lcov
            Export coverage data in "lcov" format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=lcov`. See
            <https://llvm.net.cn/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --cobertura
            Export coverage data in "cobertura" XML format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=lcov` and then converts to cobertura.xml.
            See <https://llvm.net.cn/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --codecov
            Export coverage data in "Codecov Custom Coverage" format

            If --output-path is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov export -format=json` and then converts to codecov.json.
            See <https://llvm.net.cn/docs/CommandGuide/llvm-cov.html#llvm-cov-export> for more.

        --text
            Generate coverage report in “text” format

            If --output-path or --output-dir is not specified, the report will be printed to stdout.

            This internally calls `llvm-cov show -format=text`. See
            <https://llvm.net.cn/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.

        --html
            Generate coverage report in "html" format

            If --output-dir is not specified, the report will be generated in `target/llvm-cov/html`
            directory.

            This internally calls `llvm-cov show -format=html`. See
            <https://llvm.net.cn/docs/CommandGuide/llvm-cov.html#llvm-cov-show> for more.

        --open
            Generate coverage reports in "html" format and open them in a browser after the
            operation.

            See --html for more.

        --summary-only
            Export only summary information for each file in the coverage data

            This flag can only be used together with --json, --lcov, or --cobertura.

        --output-path <PATH>
            Specify a file to write coverage data into.

            This flag can only be used together with --json, --lcov, --cobertura, or --text.
            See --output-dir for --html and --open.

        --output-dir <DIRECTORY>
            Specify a directory to write coverage report into (default to `target/llvm-cov`).

            This flag can only be used together with --text, --html, or --open. See also
            --output-path.

        --failure-mode <any|all>
            Fail if `any` or `all` profiles cannot be merged (default to `any`)

        --ignore-filename-regex <PATTERN>
            Skip source code files with file paths that match the given regular expression

        --show-instantiations
            Show instantiations in report

        --no-cfg-coverage
            Unset cfg(coverage), which is enabled when code is built using cargo-llvm-cov

        --no-cfg-coverage-nightly
            Unset cfg(coverage_nightly), which is enabled when code is built using cargo-llvm-cov
            and nightly compiler

        --no-report
            Run tests, but don't generate coverage report

        --no-clean
            Build without cleaning any old build artifacts

        --fail-under-functions <MIN>
            Exit with a status of 1 if the total function coverage is less than MIN percent

        --fail-under-lines <MIN>
            Exit with a status of 1 if the total line coverage is less than MIN percent

        --fail-under-regions <MIN>
            Exit with a status of 1 if the total region coverage is less than MIN percent

        --fail-uncovered-lines <MAX>
            Exit with a status of 1 if the uncovered lines are greater than MAX

        --fail-uncovered-regions <MAX>
            Exit with a status of 1 if the uncovered regions are greater than MAX

        --fail-uncovered-functions <MAX>
            Exit with a status of 1 if the uncovered functions are greater than MAX

        --show-missing-lines
            Show lines with no coverage

        --include-build-script
            Include build script in coverage report

        --dep-coverage <NAME>
            Show coverage of the specified dependency instead of the crates in the current workspace. (unstable)

        --skip-functions
            Skip exporting per-function coverage data.

            This flag can only be used together with --json, --lcov, or --cobertura.

        --branch
            Enable branch coverage. (unstable)

        --doctests
            Including doc tests (unstable)

            This flag is unstable. See <https://github.com/taiki-e/cargo-llvm-cov/issues/2> for
            more.

        --no-run
            Generate coverage report without running tests

        --no-fail-fast
            Run all tests regardless of failure

        --ignore-run-fail
            Run all tests regardless of failure and generate report

            If tests failed but report generation succeeded, exit with a status of 0.

    -q, --quiet
            Display one character per test instead of one line

        --lib
            Test only this package's library unit tests

        --bin <NAME>
            Test only the specified binary

        --bins
            Test all binaries

        --example <NAME>
            Test only the specified example

        --examples
            Test all examples

        --test <NAME>
            Test only the specified test target

        --tests
            Test all tests

        --bench <NAME>
            Test only the specified bench target

        --benches
            Test all benches

        --all-targets
            Test all targets

        --doc
            Test only this library's documentation (unstable)

            This flag is unstable because it automatically enables --doctests flag. See
            <https://github.com/taiki-e/cargo-llvm-cov/issues/2> for more.

    -p, --package <SPEC>
            Package to run tests for

        --workspace
            Test all packages in the workspace

        --all
            Alias for --workspace (deprecated)

        --exclude <SPEC>
            Exclude packages from both the test and report

        --exclude-from-test <SPEC>
            Exclude packages from the test (but not from the report)

        --exclude-from-report <SPEC>
            Exclude packages from the report (but not from the test)

    -j, --jobs <N>
            Number of parallel jobs, defaults to # of CPUs

    -r, --release
            Build artifacts in release mode, with optimizations

        --profile <PROFILE-NAME>
            Build artifacts with the specified profile

    -F, --features <FEATURES>
            Space or comma separated list of features to activate

        --all-features
            Activate all available features

        --no-default-features
            Do not activate the `default` feature

        --target <TRIPLE>
            Build for the target triple

            When this option is used, coverage for proc-macro and build script will not be displayed
            because cargo does not pass RUSTFLAGS to them.

        --coverage-target-only
            Activate coverage reporting only for the target triple

            Activate coverage reporting only for the target triple specified via `--target`. This is
            important, if the project uses multiple targets via the cargo bindeps feature, and not
            all targets can use `instrument-coverage`, e.g. a microkernel, or an embedded binary.

    -v, --verbose
            Use verbose output

            Use -vv (-vvv) to propagate verbosity to cargo.

        --color <WHEN>
            Coloring: auto, always, never

        --remap-path-prefix
            Use --remap-path-prefix for workspace root

            Note that this does not fully compatible with doctest.

        --include-ffi
            Include coverage of C/C++ code linked to Rust library/binary

            Note that `CC`/`CXX`/`LLVM_COV`/`LLVM_PROFDATA` environment variables must be set to
            Clang/LLVM compatible with the LLVM version used in rustc.

        --keep-going
            Do not abort the build as soon as there is an error (unstable)

        --ignore-rust-version
            Ignore `rust-version` specification in packages

        --manifest-path <PATH>
            Path to Cargo.toml

        --frozen
            Require Cargo.lock and cache are up to date

        --locked
            Require Cargo.lock is up to date

        --offline
            Run without accessing the network

    -Z <FLAG>
            Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for
            details

    -h, --help
            Print help information

    -V, --version
            Print version information

SUBCOMMANDS:
    test
            Run tests and generate coverage report
            This is equivalent to `cargo llvm-cov` without subcommand,
            except that test name filtering is supported.
    run
            Run a binary or example and generate coverage report
    report
            Generate coverage report
    show-env
            Output the environment set by cargo-llvm-cov to build Rust projects
    clean
            Remove artifacts that cargo-llvm-cov has generated in the past
    nextest
            Run tests with cargo nextest
            This internally calls `cargo nextest run`.

默认情况下,运行测试(通过cargo test),并将覆盖率摘要打印到标准输出。

cargo llvm-cov

目前,由于需要nightly-only功能来使覆盖率对文档测试生效,因此默认禁用了文档测试。有关更多信息,请参阅#2

要运行cargo run而不是cargo test,请使用run子命令。

cargo llvm-cov run

使用HTML报告(报告将生成到target/llvm-cov/html目录)

cargo llvm-cov --html
open target/llvm-cov/html/index.html

或者

cargo llvm-cov --open

使用纯文本报告(如果没有指定--output-path,则报告将打印到标准输出)

cargo llvm-cov --text | less -R

使用JSON报告(如果没有指定--output-path,则报告将打印到标准输出)

cargo llvm-cov --json --output-path cov.json

使用lcov报告(如果没有指定--output-path,则报告将打印到标准输出)

cargo llvm-cov --lcov --output-path lcov.info

您可以通过使用cargo llvm-cov report来根据先前运行的结果以不同的格式获取覆盖率报告。

cargo llvm-cov --html          # run tests and generate html report
cargo llvm-cov report --lcov # generate lcov report

cargo llvm-cov/cargo llvm-cov run/cargo llvm-cov nextest默认清理一些构建工件以避免由于旧构建工件而产生假阳性/假阴性。当传递--no-clean--no-report--no-run时,禁用此行为,并保留旧构建工件。在使用这些标志时,建议首先运行cargo llvm-cov clean --workspace以删除可能影响覆盖率结果的艺术品。

cargo llvm-cov clean --workspace # remove artifacts that may affect the coverage results
cargo llvm-cov --no-clean

合并不同测试条件下生成的覆盖率

您可以使用--no-reportcargo llvm-cov report合并不同测试条件下生成的覆盖率。

cargo llvm-cov clean --workspace # remove artifacts that may affect the coverage results
cargo llvm-cov --no-report --features a
cargo llvm-cov --no-report --features b
cargo llvm-cov report --lcov # generate report without tests

注意:要包括对文档测试的覆盖率,您还需要将--doctests传递给cargo llvm-cov report

获取链接到 Rust 库/二进制的 C/C++ 代码的覆盖率

将环境变量CCCXXLLVM_COVLLVM_PROFDATA设置为与rustc中使用的LLVM版本兼容的Clang/LLVM,并使用--include-ffi标志运行cargo-llvm-cov。

CC=<clang-path> \
CXX=<clang++-path> \
LLVM_COV=<llvm-cov-path> \
LLVM_PROFDATA=<llvm-profdata-path> \
  cargo llvm-cov --lcov --include-ffi

已知兼容的Rust(通过rustup安装)和LLVM版本

Rust 1.60-1.77 Rust 1.78-1.80
LLVM 14-17 o x
LLVM 18 x o

获取外部测试的覆盖率

cargo testcargo runcargo nextest 作为内置命令可用,但 cargo-llvm-cov 也可以用于使用 cargo 构建的任意二进制文件(包括其他 cargo 子命令或使用 make、xtask 等的外部测试)。

# Set the environment variables needed to get coverage.
source <(cargo llvm-cov show-env --export-prefix)
# Remove artifacts that may affect the coverage results.
# This command should be called after show-env.
cargo llvm-cov clean --workspace
# Above two commands should be called before build binaries.

cargo build # Build rust binaries.
# Commands using binaries in target/debug/*, including `cargo test` and other cargo subcommands.
# ...

cargo llvm-cov report --lcov # Generate report without tests.

注意:除了 reportclean 之外,cargo-llvm-cov 的子命令可能在由 show-env 设置环境变量的上下文中无法正确工作;请考虑使用正常的 cargo/cargo-nextest 命令。

注意:为了包括 doctests 的覆盖率,还需要将 --doctests 传递给 cargo llvm-cov show-envcargo llvm-cov report

排除文件从覆盖率

要排除特定文件模式从报告中,请使用 --ignore-filename-regex 选项。

cargo llvm-cov --open --ignore-filename-regex build

排除函数从覆盖率

要排除特定函数的覆盖率,请使用 #[coverage(off)] 属性

由于 #[coverage(off)] 是不稳定的,建议与 cfg(coverage) 或 cargo-llvm-cov 设置的 cfg(coverage_nightly) 一起使用。

#![cfg_attr(coverage_nightly, feature(coverage_attribute))]

#[cfg_attr(coverage_nightly, coverage(off))]
fn exclude_from_coverage() {
    // ...
}

在以下条件下设置 cfgs

  • cfg(coverage) 在使用 cargo-llvm-cov 时始终设置(除非传递了 --no-cfg-coverage 标志)。
  • cfg(coverage_nightly) 在使用 cargo-llvm-cov 与 nightly 工具链时设置(除非传递了 --no-cfg-coverage-nightly 标志)。

Rust 1.80+ 警告上述 cfgs 为 unexpected_cfgs。解决此问题的推荐方法是向 Cargo.toml 中添加一个 lints

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly)'] }

如果您想忽略所有与 #[test] 相关的代码,请考虑使用 coverage-helper 仓库版本 0.2+。

cargo-llvm-cov 默认排除目录 tests 中包含的代码,因此您也可以用它来代替 coverage-helper 仓库。

注意: #[coverage(off)] 之前被命名为 #[no_coverage]。当在旧版的夜间版中使用 #[no_coverage] 时,将 feature(coverage_attribute) 替换为 feature(no_coverage),将 coverage(off) 替换为 no_coverage,并将 coverage-helper 0.2+ 替换为 coverage-helper 0.1。

持续集成

以下是一个GitHub Actions工作流程的示例,用于上传覆盖率到 Codecov

name: Coverage

on: [pull_request, push]

jobs:
  coverage:
    runs-on: ubuntu-latest
    env:
      CARGO_TERM_COLOR: always
    steps:
      - uses: actions/checkout@v4
      - name: Install Rust
        run: rustup update stable
      - name: Install cargo-llvm-cov
        uses: taiki-e/install-action@cargo-llvm-cov
      - name: Generate code coverage
        run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
          files: lcov.info
          fail_ci_if_error: true

目前,当使用 --lcov 标志时,在 Codecov 上 仅提供行覆盖率

通过使用 --codecov 标志而不是 --lcov 标志,您可以在 Codecov 上使用区域覆盖率。

- name: Generate code coverage
  run: cargo llvm-cov --all-features --workspace --codecov --output-path codecov.json
- name: Upload coverage to Codecov
  uses: codecov/codecov-action@v3
  with:
    token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
    files: codecov.json
    fail_ci_if_error: true

请注意,Codecov 显示区域/分支覆盖率的方式不是很好

在 VS Code 中显示覆盖率

您可以使用 Coverage Gutters 在 VS Code 中显示覆盖率。

Coverage Gutters 支持lcov风格的覆盖率文件,并在顶级或 coverage 目录中检测 lcov.info 文件。以下是生成覆盖率文件的示例命令。

cargo llvm-cov --lcov --output-path lcov.info

您可能需要点击 VS Code 底部栏中的“Watch”标签来显示覆盖率。

环境变量

您可以通过覆盖这些环境变量来更改 cargo-llvm-cov 在您系统上的行为。

  • CARGO_LLVM_COV_TARGET_DIR -- 将所有生成的工件放置的位置,相对于当前工作目录。默认为 <cargo_target_dir>/llvm-cov-target
  • CARGO_LLVM_COV_SETUP -- 控制 llvm-tools-preview 组件未安装时的行为。有关更多信息,请参阅 #219
  • LLVM_COV -- 覆盖 llvm-cov 的路径。如果您正在使用 --include-ffi 标志 或您正在使用未通过 rustup 安装的工具链,则可能需要指定这两个环境变量。必须与 rustc 中使用的 LLVM 版本兼容的 llvm-cov 版本。
  • LLVM_PROFDATA -- 覆盖 llvm-profdata 的路径。有关更多信息,请参阅 LLVM_COV 环境变量。
  • LLVM_COV_FLAGS -- 要传递给 cargo-llvm-cov 执行的所有 llvm-cov 调用的附加标志列表。有关可用选项,请参阅 LLVM 文档
  • LLVM_PROFDATA_FLAGS -- 将传递给所有 cargo-llvm-cov 执行的 llvm-profdata 调用的附加标志列表,以空格分隔。请参阅LLVM 文档以获取可用选项。
  • LLVM_PROFILE_FILE_NAME -- 覆盖 LLVM_PROFILE_FILE 的文件名(路径的最后部分)。请参阅LLVM 文档以获取可用语法。

另请参阅Cargo 读取的环境变量。cargo-llvm-cov 尊重其中许多变量。

额外的 JSON 信息

如果选择 JSON 作为输出格式(使用 --json 标志),则 cargo-llvm-cov 将在 llvm-cov 数据的根处添加额外的上下文信息。这对于依赖 cargo-llvm-cov 输出的程序可能很有帮助。

{
  // Other regular llvm-cov fields ...
  "cargo_llvm_cov": {
    "version": "0.0.0",
    "manifest_path": "/path/to/your/project/Cargo.toml"
  }
}
  • version 指定使用的 cargo-llvm-cov 版本。这允许其他程序验证使用了特定版本,并对其行为做出断言。
  • manifest_path 定义了 cargo-llvm-cov 执行的 Rust 项目的 Cargo.toml 的绝对路径。它可以帮助避免在两个程序中都重复相同的选项。

例如,当直接将 JSON 输出转发到另一个程序时

cargo-llvm-cov --json | some-program

安装

从源码

cargo +stable install cargo-llvm-cov --locked

目前,安装 cargo-llvm-cov 需要 rustc 1.73+。

cargo-llvm-cov 通常可以使用比安装所需的 Rust 版本更旧的 Cargo 版本运行(例如,cargo +1.60 llvm-cov)。目前,要运行 cargo-llvm-cov 需要 Cargo 1.60+。

从预构建的二进制文件

您可以从发布页面下载预构建的二进制文件。预构建的二进制文件适用于 macOS、Linux(gnu 和 musl)以及 Windows(静态可执行文件)。

下载 cargo-llvm-cov 的脚本示例
# Get host target
host=$(rustc -vV | grep '^host:' | cut -d' ' -f2)
# Download binary and install to $HOME/.cargo/bin
curl --proto '=https' --tlsv1.2 -fsSL https://github.com/taiki-e/cargo-llvm-cov/releases/latest/download/cargo-llvm-cov-$host.tar.gz | tar xzf - -C "$HOME/.cargo/bin"

在 GitHub Actions 上

您可以使用taiki-e/install-action 在 Linux、macOS 和 Windows 上安装预构建的二进制文件。这使得安装更快,可能避免了上游更改引起的问题

- uses: taiki-e/install-action@cargo-llvm-cov

当与nextest一起使用时

- uses: taiki-e/install-action@cargo-llvm-cov
- uses: taiki-e/install-action@nextest

通过 Homebrew

您可以从我们维护的Homebrew tap(x86_64/aarch64 macOS,x86_64/aarch64 Linux)安装 cargo-llvm-cov。

brew install taiki-e/tap/cargo-llvm-cov

或者,您可以从homebrew-core(x86_64/aarch64 macOS,x86_64 Linux)安装 cargo-llvm-cov。

brew install cargo-llvm-cov

通过 Scoop(Windows)

您可以从我们维护的Scoop bucket安装 cargo-llvm-cov。

scoop bucket add taiki-e https://github.com/taiki-e/scoop-bucket
scoop install cargo-llvm-cov

通过 cargo-binstall

您可以使用cargo-binstall安装 cargo-llvm-cov。

cargo binstall cargo-llvm-cov

通过 pacman(Arch Linux)

您可以从extra 存储库安装 cargo-llvm-cov。

pacman -S cargo-llvm-cov

已知限制

另请参阅在 rust-lang/rust 中报告的与代码覆盖率相关的问题

许可证

根据您的选择,本作品受Apache License, Version 2.0MIT许可证许可。

除非您明确声明,否则根据Apache-2.0许可证定义的任何有意提交的供您在作品中包含的贡献,将按上述方式双重许可,不附加任何额外条款或条件。

依赖项

约10-20MB
约300K SLoC