#覆盖率 #源文件 #lcov #文件格式 #文件路径 #Linux #聚合

dev bin+lib grcov

Rust 工具,用于收集和汇总多个源文件的代码覆盖率数据

41 个版本

0.8.19 2023 年 7 月 10 日
0.8.15 2023 年 3 月 27 日
0.8.13 2022 年 10 月 31 日
0.8.11 2022 年 7 月 7 日
0.3.0 2018 年 10 月 9 日

#1 in #源文件

Download history 8140/week @ 2024-04-22 7925/week @ 2024-04-29 7655/week @ 2024-05-06 8008/week @ 2024-05-13 7996/week @ 2024-05-20 7533/week @ 2024-05-27 7639/week @ 2024-06-03 8310/week @ 2024-06-10 8647/week @ 2024-06-17 8393/week @ 2024-06-24 7663/week @ 2024-07-01 8564/week @ 2024-07-08 7853/week @ 2024-07-15 9546/week @ 2024-07-22 8467/week @ 2024-07-29 8085/week @ 2024-08-05

34,430 个月下载量
用于 9 个crate

MPL-2.0 许可证

400KB
9K SLoC

grcov

Build Status codecov crates.io

grcov 收集并汇总多个源文件的代码覆盖率信息。grcov 处理 .profraw 和 .gcda 文件,这些文件可以由 llvm/clang 或 gcc 生成。grcov 还处理 lcov 文件(用于 JS 覆盖率)和 JaCoCo 文件(用于 Java 覆盖率)。支持 Linux、macOS 和 Windows。

这是一个 Mozilla 启动的项目,用于收集 Firefox 上的代码覆盖率结果。

目录

man grcov

Usage: grcov [OPTIONS] <PATHS>...

Arguments:
  <PATHS>...
          Sets the input paths to use

Options:
  -b, --binary-path <PATH>
          Sets the path to the compiled binary to be used

      --llvm-path <PATH>
          Sets the path to the LLVM bin directory

  -t, --output-types <OUTPUT TYPE>
          Comma separated list of custom output types:
          - *html* for a HTML coverage report;
          - *coveralls* for the Coveralls specific format;
          - *lcov* for the lcov INFO format;
          - *covdir* for the covdir recursive JSON format;
          - *coveralls+* for the Coveralls specific format with function information;
          - *ade* for the ActiveData-ETL specific format;
          - *files* to only return a list of files.
          - *markdown* for human easy read.
          - *cobertura* for output in cobertura format.


          [default: lcov]

  -o, --output-path <PATH>
          Specifies the output path. This is a file for a single output type and must be a folder
          for multiple output types

      --output-config-file <PATH>
          Specifies the output config file

  -s, --source-dir <DIRECTORY>
          Specifies the root directory of the source files

  -p, --prefix-dir <PATH>
          Specifies a prefix to remove from the paths (e.g. if grcov is run on a different machine
          than the one that generated the code coverage information)

      --ignore-not-existing
          Ignore source files that can't be found on the disk

      --ignore <PATH>
          Ignore files/directories specified as globs

      --keep-only <PATH>
          Keep only files/directories specified as globs

      --path-mapping <PATH>


      --branch
          Enables parsing branch coverage information

      --filter <FILTER>
          Filters out covered/uncovered files. Use 'covered' to only return covered files,
          'uncovered' to only return uncovered files

          [possible values: covered, uncovered]

      --llvm
          Speeds-up parsing, when the code coverage information is exclusively coming from a llvm
          build

      --token <TOKEN>
          Sets the repository token from Coveralls, required for the 'coveralls' and 'coveralls+'
          formats

      --commit-sha <COMMIT HASH>
          Sets the hash of the commit used to generate the code coverage data

      --service-name <SERVICE NAME>
          Sets the service name

      --service-number <SERVICE NUMBER>
          Sets the service number

      --service-job-id <SERVICE JOB ID>
          Sets the service job id

          [aliases: service-job-number]

      --service-pull-request <SERVICE PULL REQUEST>
          Sets the service pull request number

      --parallel
          Sets the build type to be parallel for 'coveralls' and 'coveralls+' formats

      --threads <NUMBER>


      --precision <NUMBER>
          Sets coverage decimal point precision on output reports

          [default: 2]

      --guess-directory-when-missing


      --vcs-branch <VCS BRANCH>
          Set the branch for coveralls report. Defaults to 'master'

          [default: master]

      --log <LOG>
          Set the file where to log (or stderr or stdout). Defaults to 'stderr'

          [default: stderr]

      --log-level <LEVEL>
          Set the log level

          [default: ERROR]
          [possible values: OFF, ERROR, WARN, INFO, DEBUG, TRACE]

      --excl-line <regex>
          Lines in covered files containing this marker will be excluded

      --excl-start <regex>
          Marks the beginning of an excluded section. The current line is part of this section

      --excl-stop <regex>
          Marks the end of an excluded section. The current line is part of this section

      --excl-br-line <regex>
          Lines in covered files containing this marker will be excluded from branch coverage

      --excl-br-start <regex>
          Marks the beginning of a section excluded from branch coverage. The current line is part
          of this section

      --excl-br-stop <regex>
          Marks the end of a section excluded from branch coverage. The current line is part of this
          section

      --no-demangle
          No symbol demangling

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

如何获取 grcov

Grcov 可以从 发行版 下载,或者如果您已安装 Rust,则可以运行 cargo install grcov

使用方法

示例:如何为 Rust 项目生成基于源的覆盖率

  1. 安装 llvm-tools 或 llvm-tools-preview 组件

    rustup component add llvm-tools-preview
    
  2. 确保以下环境变量已设置

    export RUSTFLAGS="-Cinstrument-coverage"
    
  3. 构建您的代码

    cargobuild

  4. 确保通过定义 LLVM_PROFILE_FILE 环境变量来确保每个测试运行都获得其自己的配置信息(%p 将被进程 ID 替换,%m 将被二进制签名替换)

    export LLVM_PROFILE_FILE="your_name-%p-%m.profraw"
    
  5. 运行您的测试

    cargotest

在当前工作目录中,您将看到一个 .profraw 文件已生成。此文件包含 grcov 将解析的配置信息,以及您的二进制文件。

示例:如何为 C/C++ 生成 .gcda 文件

--coverage传递给clanggcc(对于较旧的gcc版本,请传递-ftest-coverage-fprofile-arcs选项(参见gcc文档)。

示例:如何为 Rust 项目生成 .gcda 文件

需要Nightly Rust来使用基于Rust gcov的grcov。或者,您可以执行以下命令,将稳定的rustc转换为Nightly版本:export RUSTC_BOOTSTRAP=1

  1. 确保以下环境变量已设置

    export CARGO_INCREMENTAL=0
    export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
    export RUSTDOCFLAGS="-Cpanic=abort"
    

    这将确保代码删除等操作不会影响覆盖率。

  2. 构建您的代码

    cargobuild

    如果您查看target/debug/deps目录,您将看到生成了.gcno文件。这些是可能被覆盖的位置。

  3. 运行您的测试

    cargotest

    target/debug/deps/目录中,您现在还将看到.gcda文件。这些文件包含了到达这些位置的击中次数。这两组文件都是grcov的输入。

从覆盖率工件生成覆盖率报告

生成类似这样的HTML覆盖率报告

grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing -o ./target/debug/coverage/

注意:对于基于源代码的覆盖率,需要指定--binary-path参数。

您可以在target/debug/coverage/index.html中查看报告。

(或者,使用-t lcov,grcov将输出一个与lcov兼容的覆盖率报告,然后您可以将它输入到lcov的genhtml命令)。

LCOV 输出

通过传递-t lcov,您可以生成一个lcov.info文件并将其传递给genhtml

genhtml -o ./target/debug/coverage/ --show-details --highlight --ignore-errors source --legend ./target/debug/lcov.info

在Codecov上上传时,应使用LCOV输出,并使用--branch参数以支持分支覆盖率。

Coveralls 输出

覆盖率还可以生成为Coveralls格式

grcov . --binary-path ./target/debug/ -t coveralls -s . --token YOUR_COVERALLS_TOKEN > coveralls.json

grcov 与 Travis

以下是基于源代码覆盖率的.travis.yml文件的示例

language: rust

before_install:
  - curl -L https://github.com/mozilla/grcov/releases/latest/download/grcov-x86_64-unknown-linux-gnu.tar.bz2 | tar jxf -

matrix:
  include:
    - os: linux
      rust: stable

script:
    - rustup component add llvm-tools-preview
    - export RUSTFLAGS="-Cinstrument-coverage"
    - cargo build --verbose
    - LLVM_PROFILE_FILE="your_name-%p-%m.profraw" cargo test --verbose
    - ./grcov . --binary-path ./target/debug/ -s . -t lcov --branch --ignore-not-existing --ignore "/*" -o lcov.info
    - bash <(curl -s https://codecov.io/bash) -f lcov.info

以下是一个.travis.yml文件的示例

language: rust

before_install:
  - curl -L https://github.com/mozilla/grcov/releases/latest/download/grcov-x86_64-unknown-linux-gnu.tar.bz2 | tar jxf -

matrix:
  include:
    - os: linux
      rust: stable

script:
    - export CARGO_INCREMENTAL=0
    - export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
    - export RUSTDOCFLAGS="-Cpanic=abort"
    - cargo build --verbose $CARGO_OPTIONS
    - cargo test --verbose $CARGO_OPTIONS
    - |
      zip -0 ccov.zip `find . \( -name "YOUR_PROJECT_NAME*.gc*" \) -print`;
      ./grcov ccov.zip -s . -t lcov --llvm --branch --ignore-not-existing --ignore "/*" -o lcov.info;
      bash <(curl -s https://codecov.io/bash) -f lcov.info;

grcov 与 Gitlab

以下是一个.gitlab-ci.yml文件的示例,该文件将构建您的项目,然后在Gitlab理解的格式中收集覆盖率数据。假设您使用的是一个已经安装了相关工具的镜像,如果不是这种情况,请将适当的命令放在script段落的开始部分。

build:
  variables:
    # Set an environment variable which causes LLVM to write coverage data to the specified location. This is arbitrary, but the path passed to grcov (the first argument) must contain these files or the coverage data won't be noticed.
    LLVM_PROFILE_FILE: "target/coverage/%p-%m.profraw"
  script:
    # Run all your Rust-based tests
    - cargo test --workspace
    # Optionally, run some other command that exercises your code to get more coverage:
    - ./bin/integration-tests --foo bar
    # Create the output directory
    - mkdir target/coverage
    # This is a multi-line command. You can also write it all as one line if desired, just remove
    # the '|' and all the newlines.
    - |
        grcov
    # This path must match the setting in LLVM_PROFILE_FILE. If you're not getting the coverage
    # you expect, look for '.profraw' files in other directories.
        target/coverage
    # If your target dir is modified, this will need to match...
        --binary-path target/debug
    # Where the source directory is expected
        -s .
    # Where to write the output; this should be a directory that exists.
        -o target/coverage
    # Exclude coverage of crates and Rust stdlib code. If you get unexpected coverage results from
    # this (empty, for example), try different combinations of '--ignore-not-existing',
    # '--ignore "$HOME/.cargo/**"' and see what kind of filtering gets you the coverage you're
    # looking for.
        --keep-only 'src/*'
    # Doing both isn't strictly necessary, if you won't use the HTML version you can modify this
    # line.
        --output-types html,cobertura

    # Extract just the top-level coverage number from the XML report.
    - xmllint --xpath "concat('Coverage: ', 100 * string(//coverage/@line-rate), '%')" target/coverage/cobertura.xml
  coverage: '/Coverage: \d+(?:\.\d+)?/'
  artifacts:
    paths:
      - target/coverage/
    reports:
      coverage_report:
        coverage_format: cobertura
        path: target/coverage.xml

这还与Gitlab的覆盖率百分比收集相关联,因此,在合并请求中,您将能够看到

  • 覆盖率的增加或减少
  • 合并请求修改的特定代码行是否被覆盖。

此外,如果启用,将生成HTML格式的覆盖率报告作为工件。

其他报告

grcov提供以下输出类型

输出类型-t 描述
lcov(默认) 与linux覆盖率项目兼容的lcov的INFO格式。
ade ActiveData-ETL格式。仅对Mozilla项目有用。
coveralls 生成Coveralls格式的覆盖率。
coveralls+ 类似于coveralls,但包含函数级信息。
files 输出被覆盖或未覆盖的源文件列表。
covdir 以递归JSON格式提供覆盖率。
html 输出HTML覆盖率报告,包括README中的覆盖率徽章。
cobertura Cobertura XML。用于某些IDE和Gitlab CI中的覆盖率分析。

托管 HTML 报告和使用覆盖率徽章

可以将HTML报告托管在GitHub Pages、Netlify和其他静态网站提供商上。通常会在项目的readme中提供一个覆盖率徽章,以显示当前代码的覆盖率百分比。

为了仍然允许在使用静态站点主机时添加徽章,grcov会生成覆盖徽章和包含覆盖信息的JSON文件,这些文件可以与https://shieldsio.npmjs.net.cn配合使用,动态生成徽章。

https://shieldsio.npmjs.net.cn的覆盖数据可以在/coverage.json找到,生成的徽章作为SVG文件在/badges/*svg中可用。

生成的徽章设计来自shields.io,但在有任何更改时可能不会立即更新。如果已经使用了他们服务中的其他徽章,建议使用他们的端点方法。

处理覆盖数据目录时,grcov使用符号链接来避免复制文件。在Windows上,默认情况下,创建文件符号链接需要管理员权限。(原因是避免在Windows添加对符号链接支持之前设计的应用程序中的安全攻击。)

在Windows上运行时,grcov将尝试创建符号链接。如果失败,则grcov将回退到复制文件。复制效率较低,但至少允许用户运行grcov。当回退到复制文件时,grcov还将打印警告,建议用户为其账户启用权限或以管理员身份运行。

您可以启用账户的“创建符号链接”权限,这样就不需要以管理员身份运行grcov

  1. 单击“开始”,然后选择“本地组策略编辑器”。或者直接运行gpedit.msc来打开它。
  2. 在导航树中,选择“计算机配置”、“Windows设置”、“安全设置”、“本地策略”。
  3. 在右侧面板中,选择“创建符号链接”,然后双击它。
  4. 单击“添加用户或组”,并添加您的账户。
  5. 注销并重新登录。

示例

假设我们有一个名为sample的用户和项目awesome,该项目托管在GitHub Pages上,网址为https://sample.github.io/awesome

通过使用shields.io端点,我们可以创建如下Markdown徽章

[![coverage](https://shieldsio.npmjs.net.cn/endpoint?url=https://sample.github.io/awesome/coverage.json)](https://sample.github.io/awesome/index.html)

如果我们想避免使用shields.io,我们可以如下使用生成的徽章(注意图像URL的不同)

[![coverage](https://sample.github.io/awesome/badges/flat.svg)](https://sample.github.io/awesome/index.html)

自动格式化

此项目使用pre-commit。请运行pre-commit install在您的克隆中安装git pre-commit钩子。有关安装pre-commit的说明,请参阅此处

每次尝试提交时,pre-commit都会在您的文件上运行检查,以确保它们遵循我们的样式标准且未受一些简单问题的干扰。如果检查失败,pre-commit将不允许您提交。

构建 & 测试

构建方式

cargo build

运行单元测试

cargo test --lib

要运行集成测试,建议使用在tests/Dockerfile中定义的Docker镜像。只需构建镜像即可运行它们

docker build -t marcocas/grcov -f tests/Dockerfile .

否则,如果您不想使用Docker,唯一的前提是安装GCC 7,设置GCC_CXX环境变量为g++-7GCOV环境变量为gcov-7。然后运行以下命令进行测试

cargo test

最低要求

  • 需要GCC 4.9或更高版本(如果解析由GCC生成的覆盖率工件)。
  • Rust 1.52

许可证

根据MPL 2.0许可证发布。

依赖项

~18–29MB
~461K SLoC