此章节:

说明

C/C++test 的多指标覆盖率分析使您可以在执行 C/C++test 之外的独立应用程序或库时监视代码覆盖率。

C/C++test 附带一个独立的覆盖程序包,该程序包包含以下组件:

  • <INSTALL_DIR>/bin/cpptestcc - 一种集成到构建过程中的覆盖率工具,用于程序插桩以收集原始覆盖率数据。
  • <INSTALL_DIR>/bin/engine/coverage/runtime- 需要与程序插桩集成的覆盖率运行时库。
使用cpptestcc收集覆盖率 涉及三个阶段:

  1. 通过将 cpptestcc 工具集成到构建中来对程序插桩。
  2. 执行插桩代码并收集原始覆盖率数据。
  3. 通过使用内建测试配置将原始覆盖率数据导入到 C/C++test 中来检查 C/C++test 的覆盖率。

cpptestcc快速入门

  1. 将路径添加到 <INSTALL_DIR>/bin  PATH 系统变量 以启用 cpptestcc 工具的执行。

  2. 更新编译命令,以将cpptestcc可执行文件作为编译器命令的前缀,并以-- 作为分隔符。 示例:

    原始编译命令行

    cc -I app/includes -D defines -c source.cpp

    更新编译命令行

    cpptestcc -compiler gcc_7 -line-coverage -- cc -I app/includes -D defines -c source.cpp
    至少,cpptestcc 工具需要在命令行上配置以下参数:

    - a compiler identifier: -compiler <COMPILER_ID>

    -覆盖率指标(例如, -decision-coverage)

    有关其他选项的信息,请参见Command Line Reference for cpptestcc

  3. 使用 C/C++test 附带的预构建覆盖率运行时库的路径更新您的链接器命令,以将该库添加到您的应用程序中。示例:

    原始命令行

    lxx -L app/lib app/source.o somelib.lib -o app.exe

    更新命令行

    lxx -L app/lib app/source.o somelib.lib [INSTALL_DIR]/bin/engine/coverage/runtime/lib/cpptest.lib -o app.exe

    重要

    如果覆盖率运行时库链接为共享(动态负载)库,则必须确保在启动程序插桩时可以加载它。这通常需要添加 <INSTALL_DIR>/bin/engine/coverage/runtime/bin PATH 环境变量 (在 Windows 上) 或者 <INSTALL_DIR>/bin/engine/coverage/runtime/lib  到 LD_LIBRARY_PATH 环境变量 (在 Linux 上)。

    C/C++test 为本地 Windows 和 Linux 应用程序提供了预先构建的覆盖率运行时库。对于跨平台和嵌入式测试,运行时库需要从可用的源构建 <INSTALL_DIR>/bin/engine/coverage/runtime. 有关详细信息,请参见覆盖率运行时库

  4. 构建应用程序。插桩代码时,cpptestcc 将创建 .cpptest/cpptestcc 文件夹,其中存储了与覆盖率相关的重要数据(“覆盖率图”)。默认情况下,该文件夹位于当前编辑的工作目录中。您可以使用-workspace <path>选项更改默认位置;请参见 Command Line Reference for cpptestcc有关详细信息。 
  5. 运行应用程序。覆盖率数据(“覆盖率日志”)将存储在cpptest_results.clog文件中。
  6. 在安装了 C/C++test 的 IDE 中,创建一个新项目,其中包含应用程序的所有源文件。
    (info)确保文件和所有路径保持不变。
  7. 选择项目并从 IDE 菜单中选择Parasoft> 测试配置> 实用程序> 加载应用程序覆盖率以导入覆盖率数据(有关详细信息,请参见Importing the Coverage Data)。
  8. 查看覆盖率信息(请参见查看覆盖率信息)。

导入覆盖率数据

加载应用程序覆盖率测试配置假定 .cpptest/cpptestcc 文件夹和 cpptest_results.clog文件都存储在默认位置。要自定义位置,请在测试配置中配置以下执行详细信息(执行> 常规> 执行详细信息):
-覆盖率图文件的根位置 - 默认:${project_loc}/.cpptest/cpptestcc
覆盖率日志文件 - 默认:${project_loc}/*.clog

默认情况下,加载应用程序覆盖率测试配置尝试加载有关所有受支持的覆盖率指标的信息。要自定义受支持的覆盖率指标列表,跳转到 执行> 常规> 执行细节> 检测模式> 检测功能> C/C++ 代码覆盖率指标 然后选择您想要报告的指标。

我们建议您与在编译命令行中为cpptestcc工具启用的度量指标保持一致。

收集 CMake 项目的应用程序覆盖率

C/C++test 附带了 CMake 的扩展,允许您将 C/C++test 的代码覆盖率分析直接集成到您的 CMake 项目中。该扩展程序会自动修改您的编译器/链接器命令行,以在构建项目时使用cpptestcc 覆盖率工具。因此,在您运行程序插桩或执行功能或单元测试后,将创建 C/C++test 覆盖率日志文件 (.clog)。然后可以使用覆盖率日志文件生成完整的代码覆盖率报告。

对 CMake 集成的支持包括:

  • <CPPTEST_INSTALL_DIR>/integration/cmake/cpptest-coverage.cmake 扩展 – 您需要添加到 CMakeFiles.txt 构建文件中的 CMake 的 C/C++test 扩展文件。
  • <CPPTEST_INSTALL_DIR>/integration/cmake/cpptest.templates/* 中的模板–一组用于生成 C/C++test (Eclipse) 项目的 C/C++test 模板。
  • CPPTEST_COVERAGE=ONCPPTEST_HOME=<CPPTEST_INSTALL_DIR> 选项–扩展程序提供的选项,用于在使用 CMake 构建应用程序时激活扩展程序。
  • cpptest_coverage_report 目标 – 扩展提供的目标,用于使用.clog 文件作为输入生成覆盖率报告。

此外,<CPPTEST_INSTALL_DIR>/examples/Timer 目录包含一个示例项目,用于演示为 CMake 项目收集代码覆盖率。

需求

  • 带有 Unix Makefiles 或 Ninja 生成器的 CMake 3.10 或更新版本

其他先决条件:

  • 必须执行应用程序的完整构建以收集 CMake 项目的代码覆盖率。不支持增量构建。
  • 在 Windows 上,您的 CMake 项目和工具链需要配置为使用带有正斜杠或反斜杠的 Windows 路径(例如,c:/folder/source.cppc:\folder\source.cpp)。Windows 不支持 Unix 样式的路径(例如,/c/folder/source.cpp)。

工作流概述

  1. <CPPTEST_INSTALL_DIR>/integration/cmake/cpptest-coverage.cmake<CPPTEST_INSTALL_DIR>/integration/cmake/cpptest.templates/*复制到您的 CMake 项目。
  2. 查看 cpptest-coverage.cmake  文件中的覆盖率配置详细信息,并根据需要更新选项。  至少,您必须确保使用 CPPTEST_COMPILER_ID选项指定的编译器配置与您的编译器相匹配。有关可用选项,请参阅 自定义 CMake 的覆盖率扩展

  3. cpptest-coverage.cmake 扩展添加到您的主 CMakeLists.txt 构建文件中。扩展必须在所有构建目标定义之前,以确保自动修改编译器/链接器命令行。
  4. 在配置和构建 CMake 项目时,使用 CPPTEST_COVERAGE 和 CPPTEST_HOME 选项激活扩展:

    > cmake -DCPPTEST_COVERAGE=ON -DCPPTEST_HOME=<CPPTEST_INSTALL_DIR> ..

    默认情况下,C/C++test 的覆盖率数据文件将在 <CMAKE_SOURCE_DIR>/../cpptest-coverage/<CMAKE_PROJECT_NAME>/.cpptest 中创建。

  5. 运行您的应用程序或执行您的功能或单元测试。
    默认情况下,C/C++test 覆盖率日志文件 (.clog) 将在 <CMAKE_SOURCE_DIR>/../cpptest-coverage/<CMAKE_PROJECT_NAME>/<CMAKE_PROJECT_NAME>.clog中创建 。
  6. 运行  cpptest_coverage_report  助手目标以生成覆盖率报告:

    > make cpptest_coverage_report

    C/C++test 目标将创建:
    - 一个可以直接在 IDE 中打开的工作空间:<CMAKE_SOURCE_DIR>/../cpptest-coverage
    - 一个该工作空间中的 C/C++test (Eclipse) 项目:<CMAKE_SOURCE_DIR>/../cpptest-coverage/<CMAKE_PROJECT_NAME>
    - 报告目录中的覆盖率报告: <CMAKE_SOURCE_DIR>/../cpptest-coverage/<CMAKE_PROJECT_NAME>/reports

    我们建议使用 cpptest_coverage_report 目标生成覆盖率报告。或者,您可以将 C/C++test 与加载应用程序覆盖率测试配置结合使用,从 <CMAKE_SOURCE_DIR>/../cpptest-coverage/<CMAKE_PROJECT_NAME>中收集的覆盖率数据生成报告。有关详细信息,请参见 Importing the Coverage Data

自定义 CMake 的覆盖率扩展

要使用 C/C++test 扩展自定义收集覆盖率,请打开您复制到 CMake 项目的 cpptest-coverage.cmake 文件并修改 C/C++test 选项。 

选项名称说明默认
CPPTEST_COMPILER_ID

指定与您的编译器匹配的编译器配置。

gcc_9-64
 CPPTEST_COVERAGE_TYPE_FLAGS 指定覆盖率类型。请参阅 Command Line Reference for cpptestcc 以了解可用选项。-optimized-line-coverage
CPPTEST_COVERAGE_WORKSPACE指定覆盖率工具的工作空间路径 默认情况下存储 C/C++test 的覆盖率数据文件。<CMAKE_SOURCE_DIR>/../cpptest-coverage/<CMAKE_PROJECT_NAME>
CPPTEST_COVERAGE_LOG_FILE

指定 C/C++test 覆盖率日志文件(.clog)的名称和位置。

重要:在运行程序插桩之前,您必须确保覆盖率日志目录存在。

<CPPTEST_COVERAGE_WORKSPACE>/<CMAKE_PROJECT_NAME>.clog
CPPTEST_CPPTESTCC_OPTS指定cpptestcc 覆盖率工具的选项。

此外,您可能需要查看:

  • cpptest_coverage_report 目标的定义,指定 cpptestcli 生成覆盖率报告的参数。
  • # Build C/C++test 覆盖率运行时库部分,其中包括 C/C++test 运行时库的配置(该库由覆盖率扩展自动构建)。
  • CPPTEST_LINKER_FLAGS 选项,它定义了 C/C++test 覆盖率运行时将如何链接。

将覆盖率扩展与 CMake 集成的示例

本节演示如何使用 C/C++test 的 CMake 覆盖率扩展为位于 <CPPTEST_INSTALL_DIR>/examples/Timer 目录中的示例项目收集覆盖率数据。Timer 项目配置为使用 <CPPTEST_INSTALL_DIR>/integration/cmake 中提供的 cpptest-coverage.cmake 扩展。

收集示例项目的覆盖率:

  1. 如果您使用默认 GNU GCC 9 (x64) 以外的编译器,请转到 <CPPTEST_INSTALL_DIR>/integration/cmake/cpptest-coverage.cmake 并修改 CPPTEST_COMPILER_ID 的默认值以匹配您的编译器。
  2. 构建示例项目:

    > cd <CPPTEST_INSTALL_DIR>/examples/Timer
    > mkdir build
    > cd build
    > cmake -DCPPTEST_COVERAGE=ON -DCPPTEST_HOME=<CPPTEST_INSTALL_DIR> ..
    > make
  3. 运行应用程序:

    > ./timer
  4. 生成覆盖率报告:

    > make cpptest_coverage_report

    该报告将在 <CPPTEST_INSTALL_DIR>/examples/cpptest-coverage/Timer/reports中创建。

  5. (可选)启动 C/C++test GUI 并打开 <CPPTEST_INSTALL_DIR>/examples/cpptest-coverage 工作空间以查看 IDE 中的覆盖率详细信息。

cpptestcc的命令行参考

(info) 您可以运行以下命令以将可用选项打印到控制台:cpptestcc -help

提供以下选项:

-compiler <name|path>

指定您想要用于代码分析和插桩的编译器配置的名称。有关支持的编译器的列表,请参见编译器 或使用 -list-compilers 命令行选项将支持的编译器的列表打印到控制台。

示例:

cpptestcc -compiler gcc_3_4 

cpptestcc -compiler vc_11_0

配置文件格式(请参见 -psrc): cpptestcc.compiler <name>

-list-compilers

打印出所有受支持的编译器配置的名称。

配置文件格式(请参见 -psrc):cpptestcc.listCompilers

-include <file|pattern> 和 -exclude <file|pattern>

将与指定模式匹配的所有文件包括在插桩范围内或从插桩范围中排除。

仅在按照其指定顺序指定了所有包含/排除条目之后,才确定最终过滤。

支持以下通配符:

  • ? - 任何字符
  • * - 任意字符序列

为了防止外壳程序将 * 通配符扩展到文件或目录列表,可以使用 regex: 前缀指定值。

(info) 可以多次指定这些选项。

配置文件格式(请参见 -psrc): cpptestcc.include <path|pattern>

示例 1:

示例项目布局:

<project root>
 + external_libs
 + src
 + include

如果您的项目具有上述布局,则以下命令将从程序插桩范围中排除external_libs目录中的所有文件:

cpptestcc -include regex:*/<project root>/* -exclude regex:*/<project root>/external_libs <other command line options>

示例 2:

示例项目布局:

<project root> 
<sourcefiles>.cpp 
<headerfiles>.hpp

如果您的项目具有上述布局,则以下命令将仅插桩头文件(不插桩源文件):

cpptestcc -include regex:*-exclude regex:*.cpp <remaining part of cmd>

-ignore <pattern>

指定在处理期间将被忽略的源文件。符合指定模式的文件将被编译,但不会被解析或插桩。

-ignore vs. -exclude

-ignore 选项将指定的文件完全从处理中删除,以便覆盖率引擎不解析该文件。

-include/-exclude 过滤器在解析源代码后应用,这使您可以有选择地插桩或不插桩文件头文件。

您可以使用-ignore 选项,通过忽略代码某些部分(例如外部库)的覆盖率分析来减少构建时间,或忽略处理过程中暴露出解析错误或其他问题的指定文件。

支持以下通配符:

  • ? - 任何字符
  • * - 任意字符序列

为了防止外壳程序将 * 通配符扩展到文件或目录列表,可以使用 regex: 前缀指定值。

(info) 可以多次指定此选项。

配置文件格式(请参见 -psrc): cpptestcc.ignore <path|pattern>

示例:

cpptestcc -ignore "*/Lib/*" <remaining part of cmd>
cpptestcc -ignore regex:*/file.c <remaining part of cmd>
cpptestcc -ignore c:/proj/file.c <remaining part of cmd>
cpptestcc -ignore "*/MyLib/*.cpp" -ignore file.cpp <remaining part of cmd>

-line-coverage

启用收集行覆盖率。

执行代码时,会将运行时覆盖率结果写入到结果日志中。这一操作增加了测试的代码执行时间,但是它使您即使在应用程序崩溃时也可以确保收集覆盖率数据。

配置文件格式(请参见 -psrc): cpptestcc.lineCoverage [true|false]

-optimized-line-coverage

启用 收集优化的行覆盖率。

运行时覆盖率结果存储在内存中,然后在应用程序完成后或应用户请求写入结果日志。这样可以提高性能,但是如果应用程序崩溃,结果可能会丢失。

配置文件格式(请参见-psrc): cpptestcc.optimizedLineCoverage [true|false]

-function-coverage

启用收集 函数覆盖率。

配置文件格式(请参见 -psrc): cpptestcc.functionCoverage [true|false]

-optimized-function-coverage

启用收集优化的函数覆盖率。配置文件格式(请参见 -psrc):

cpptestcc.optimizedFunctionCoverage [true|false]

-statement-coverage

启用收集 语句覆盖率。配置文件格式(请参见 -psrc):

cpptestcc.statementCoverage [true|false]

-optimized-statement-coverage

启用收集 语句覆盖率。

配置文件格式(请参见-psrc): cpptestcc.optimizedStatementCoverage [true|false]

-block-coverage

启用收集 块覆盖率。

配置文件格式(请参见 -psrc): cpptestcc.blockCoverage [true|false]

-optimized-block-coverage

启用收集优化的块覆盖率。

配置文件格式(请参见-psrc): cpptestcc.optimizedBlockCoverage [true|false]

-path-coverage

启用收集路径覆盖率。

配置文件格式(请参见 -psrc): cpptestcc.pathCoverage [true|false]

-decision-coverage

启用收集 决策覆盖率。

配置文件格式(请参见 -psrc): cpptestcc.decisionCoverage [true|false]

-optimized-decision-coverage

启用 收集优化的决策覆盖率。

配置文件格式(请参见-psrc): cpptestcc.optimizedDecisionCoverage [true|false]

-simple-condition-coverage

启用收集简单的条件覆盖率。

配置文件格式(请参见-psrc): cpptestcc.simpleConditionCoverage [true|false]

-optimized-simple-condition-coverage

启用收集优化的简单条件覆盖率。

配置文件格式(请参见-psrc): cpptestcc.optimizedSimpleConditionCoverage [true|false]

-mcdc-coverage

启用 收集 MC/DC 覆盖率。

配置文件格式(请参见 -psrc): cpptestcc.mcdcCoverage [true|false]

-call-coverage

启用收集 调用覆盖率。

配置文件格式(请参见 -psrc): cpptestcc.callCoverage [true|false]

-optimized-call-coverage

启用 收集优化的调用覆盖率。

配置文件格式(请参见-psrc): cpptestcc.optimizedCallCoverage [true|false]

-coverage-early-init

在应用程序入口点的开头启用覆盖率模块。

配置文件格式(请参见 -psrc): cpptestcc.coverageEarlyInit [true|false]

-coverage-auto-finalization

如果启用,将在应用程序退出时自动完成收集覆盖率。默认情况下启用此选项。

配置文件格式(请参见 -psrc): cpptestcc.coverageAutoFinalization [true|false]

-optimized-coverage-corruption-detection

启用损坏检测算法以优化覆盖率指标。

配置文件格式(请参见 -psrc): cpptestcc.optimizedCoverageCorruptionDetection[true|false]

-template-coverage

启用对模板类和函数的收集覆盖率

配置文件格式(请参见 -psrc): cpptestcc.templateCoverage [true|false]

-coverage-data-variants

允许为同一源文件的不同编译存储覆盖率数据的多个变体。

默认情况下,cpptestcc 在每次构建时为每个源文件收集一次覆盖率数据。在构建期间多次编译源文件的极少数情况下,您可以使用此选项为同一源文件存储覆盖率数据的多个变体——每次编译一个变体。

此选项不支持由同一源文件的多次编译引入冲突代码的情况。

-disable-auto-recovery-mode

禁用覆盖率插桩的自动恢复模式。

默认情况下,当无法成功插桩文件时,将在构建中使用该文件的原始(非插桩)版本。指定此选项后,如果出现插桩问题,构建将失败并显示错误。

-workspace <path>

指定一个自定义目录,有关代码结构的信息将在代码分析和插桩期间存储在该目录中。cpptestcli 工具将使用该信息生成最终的覆盖率报告。

默认情况下,该信息存储在当前编辑的工作目录中。如果您的编译使用多个工作目录,建议您指定一个自定义目录,以确保所有覆盖率数据都存储在同一位置。

配置文件格式 (请参见 -psrc): cpptestcc.workspace <path>

-techsupport

 使用从工作空间收集的诊断文件创建归档(请参阅-workspace)。归档将存储在当前工作目录中。

示例:

cpptestcc -techsupport

cpptestcc -techsupport -workspace path/to/workspace-dir

-psrc <file>

指定配置文件的路径,您可以在其中配置其他cpptestcc选项。

默认情况下,cpptestcc 尝试读取位于当前工作目录或用户主目录中的.psrc 文件。此选项允许您指定配置文件的自定义位置。

(info) 如果在命令行和配置文件中都配置了选项,则cpptestcc将使用命令行中指定的值。

-status

-status-verbose

显示从工作空间收集的诊断数据(请参阅-workspace),包括错误和警告信息、文件数量等。

使用 -status-verbose 显示更详细的信息。

示例:

cpptestcc -status

cpptestcc -status -workspace path/to/workspace-dir

cpptestcc -status-verbose

cpptestcc -status-verbose -workspace path/to/workspace-dir

-version

打印出有关版本的信息

-help

打印出帮助消息并退出。

覆盖率运行时库

覆盖率运行时库是源代码插桩用于在应用程序运行时发出覆盖率信息的帮助程序函数和服务的集合。没有该库,无法链接程序插桩。运行时库可以根据测试的项目类型以多种方式链接到最终的可测试二进制文件。

除了为已插桩代码提供基本服务外,该库还用于使代码覆盖解决方案适应特定的开发环境,例如支持非标准传输以在测试的嵌入式设备和开发主机之间提供覆盖结果。

预先构建的版本和自定义的构建

C/C++test 附带了运行时库的预构建版本,这些版本适合在安装 C/C++test 的同一平台上使用。在大多数情况下,从本地开发的应用程序收集代码覆盖率信息可以使用运行时库的预构建版本。

开发跨平台应用程序的所有用户都需要使用合适的交叉编译器和可能的链接器来准备覆盖率运行时库的自定义版本。C/C++test 附带了代码覆盖率运行时库的源代码。

准备覆盖率运行时库自定义构建的过程通常仅限于覆盖率运行时库源代码的编译。在某些情况下,您可能需要安装一些源代码片段以使代码覆盖率适应特定的开发平台。以下各节介绍了此过程。

使用预构建的运行时库

C/C++test 包含以下二进制文件:

Windows (x86 和 x86-64) 

文件说明
<INSTALL_DIR>/bin/engine/coverage/runtime/lib/cpptest.aCygwin GNU GCC 编译器使用的 32 位导入库。添加到链接命令行中。
<INSTALL_DIR>/bin/engine/coverage/runtime/lib/cpptest64.aCygwin GNU GCC编译器一起使用的 64 位导入库。添加到链接命令行中。
<INSTALL_DIR>/bin/engine/coverage/runtime/lib/cpptest.lib与 Microsoft Visual C++ 编译器一起使用的 32 位导入库。添加到链接命令行中。
<INSTALL_DIR>/bin/engine/coverage/runtime/lib/cpptest64.lib与 Microsoft Visual C++ 编译器一起使用的 64 位导入库。添加到链接命令行中。
<INSTALL_DIR>/bin/engine/coverage/runtime/bin/cpptest.dll32 位动态链接库。<INSTALL_DIR>/bin/engine/coverage/runtime/bin 应添加到 PATH 环境变量。
<INSTALL_DIR>/bin/engine/coverage/runtime/bin/cpptest64.dll64 位动态链接库。<INSTALL_DIR>/bin/engine/coverage/runtime/bin 应添加到 PATH 环境变量。
Windows (x86 和 x86-64)
文件说明
<INSTALL_DIR>/bin/engine/coverage/runtime/lib/libcpptest.so32 位共享库。要添加链接命令行。<INSTALL_DIR>/bin/engine/coverage/runtime/lib 应该添加到 LD_LIBRARY_PATH
<INSTALL_DIR>/bin/engine/coverage/runtime/lib/libcpptest64.so64 位共享库。要添加链接命令行。<INSTALL_DIR>/bin/engine/coverage/runtime/lib应该添加到LD_LIBRARY_PATH

如果需要以未作为即用型解决方案提供的形式使用运行时库,请准备一个符合特定开发环境要求的覆盖率运行时库的自定义版本。更多详细信息请参见 自定义运行时库.

与链接器命令行集成

将覆盖率运行时库与经过测试的应用程序链接过程集成在一起,通常需要修改链接器命令行,在某些情况下还需要修改执行环境。本节介绍使用 C/C++test 附带的预构建版本时如何修改链接过程。

Windows Cygwin GNU GCC 编译器的静态库:

  1. 在构建脚本中找到链接器命令行
  2. 修改构建脚本,以便在链接器命令行中的某个位置(最好在所有目标文件之后)指定覆盖率运行时库。

Microsoft Visual C++ 编译器的动态链接库:

  1. 在构建脚本中找到链接器命令行
  2. 修改构建脚本,以便在链接器命令行中的某个位置(最好在所有目标文件之后)指定覆盖率运行时库。示例:

    $(LXX) $(PRODUCT_OBJ) $(OFLAG_EXE)$(PROJ_EXECUTABLE) $(LXXFLAGS) $(SYSLIB) $(EXECUTABLE_LIB_LXX_OPTS) <INSTALL_DIR>/bin/engine/coverage/runtime/lib/cpptest.lib

  3. 确保将 lib 目录的路径添加到 PATH 环境变量中,以便在启动被测程序时可以定位到该库。您还可以考虑将 cpptest.dll(或cpptest64.dll)文件复制到与可执行文件相同的目录中,或复制到在测试的应用程序启动过程中扫描动态链接库的其他位置。

Linux GNU GCC 编译器的共享库:

  1. 在构建脚本中找到链接器命令行
  2. 修改构建脚本,以便在链接器命令行中的某个位置(最好在所有目标文件之后)指定覆盖率运行时库。示例:

    $(LXX) $(PRODUCT_OBJ) $(OFLAG_EXE)$(PROJ_EXECUTABLE) $(LXXFLAGS) $(SYSLIB) $(EXECUTABLE_LIB_LXX_OPTS) -L <INSTALL_DIR>/bin/engine/coverage/runtime/lib -lcpptest
    请注意,添加了-L-lcpptest 选项。

  3. 确保将 lib 目录的路径添加到 LD_LIBRARY_PATH 环境变量中,以允许被测试的可执行文件找到共享库的路径。

自定义运行时库

由于以下情况,您可能需要自定义运行时库:

  • 需要不同形式的二进制文件
  • 为结果传输启用非默认通信通道
  • 安装用于结果传输的通信通道的自定义实现
  • 启用对多线程应用程序的非默认支持
  • 安装对多线程应用程序的支持的自定义实现

库源代码结构

运行时库源代码在 [INSTALL_DIR]/bin/engine/coverage/runtime目录中随 C/C++test 一起提供。下表描述了结构: 

部件说明
包括

包含库包含文件的目录。
include/cpptest.h - 库公共接口
include/cpptest/* - 库私有接口
包含目录的内容不是为特定于环境的修改而设计的。

src

包含库源代码的目录。
src/cpptest.c - 运行时库的主源文件和单个源文件。
该文件旨在进行修改和自定义。

生成文件提供了用于构建运行时库的基本生成文件。
目标包含一组 Makefile 的目录包含带有编译器特定选项的文件,用于为最流行的开发环境准备运行时库构建。
信道包含一组 Makefile 的目录包含具有支持的通信信道配置的文件。

交换通信信道支持

运行时库支持通过各种通信信道进行数据收集。使用的通信信道取决于开发环境。在大多数情况下,将结果存储在一个或多个文件中是适当的,但可能需要在其他 TCP/IP 套接字或 RS232 传输中进行。通过在cpptest.c库源文件编译期间将值设置为专用宏,可以启用特定的通信通道。将-D<MACRO> 添加到编译命令行以设置值。下表提供了通信通道控制宏的完整列表:  

信道说明
CPPTEST_NULL_COMMUNICATION空实现。如果启用,将不发送任何结果。适用于初始测试构建和调试。
CPPTEST_FILE_COMMUNICATION

基于文件的实现。使用 ANSI C 文件 I/O 接口。如果启用,结果将写入本地驱动器文件。

还提供以下附加配置宏:

CPPTEST_LOG_FILE_NAME: 结果文件名称;默认 cpptest_results.clog

CPPTEST_LOG_FILE_APPEND:创建新的结果文件或追加到现有结果文件。默认值为 1 -> , 替代 0 -> 创建新建

CPPTEST_SPLIT_FILE_COMMUNICATION

基于文件的实现。使用 ANSI C 文件 I/O 接口。如果启用,结果将被写入一系列本地驱动器文件中。

您可以使用以下宏配置此信道:

CPPTEST_LOG_FILE_NAME: 系列中第一个结果文件的名称;默认是 cpptest_results.clog。其他文件将按顺序命名,例如, cpptest_results.clog.0001

确保系列中的所有文件都放在同一目录中。

CPPTEST_MAX_ALLOWED_NUMBER_OF_BYTES_PER_FILE: 指定系列中一个文件的最大大小;默认值 2000000000 字节(2 GB)。

CPPTEST_UNIX_SOCKET_COMMUNICATION

基于 TCP/IP 套接字的实现。使用 POSIX API。如果启用,结果将发送到指定的 TCP/IP 端口。提供了以下其他配置宏:

CPPTEST_LOG_SOCKET_HOST: 指定主机 IP 地址字符串

CPPTEST_LOG_SOCKET_PORT: 指定端口号

CPPTEST_GETHOSTBYNAME_ENABLED: 如果设置为 1,则可以通过域名指定主机(要求存在gethostbyname函数)

CPPTEST_WIN_SOCKET_COMMUNICATION如上所述,使用 Windows API。
CPPTEST_UNIX_SOCKET_UDP_COMMUNICATION如上所述,基于 UDP 的实现。
CPPTEST_RS232_UNIX_COMMUNICATION

基于 RS232 的实现。使用 POSIX API。如果启用,则结果通过指定的 RS232 系统设备发送。提供了以下其他配置宏:

CPPTEST_RS232_DEVICE_NAME: 系统设备名称

CPPTEST_RS232_BAUD_RATE: 传输波特率

CPPTEST_RS232_BYTE_SIZE: 字节大小

CPPTEST_RS232_PARITY: 奇偶控制

CPPTEST_RS232_STOP_BIT: 停止位使用

CPPTEST_RS232_TIMEOUT: 传输超时值

CPPTEST_RS232_WIN_COMMUNICATION如上。使用 Windows API。
CPPTEST_RS232_STM32F103ZE_COMMUNICATION基于 STM32F103x USART 的实现。使用 STM Cortex 库接口(ST/STM32F10x/stm32f10x.h 头文件是必需的)
CPPTEST_HEW_SIMIO_COMMUNICATIONRenesas HEW 模拟器的特定实现。
CPPTEST_LAUTERBACH_FDX_COMMUNICATION基于 Lauterbach TRACE32 的实现(使用 FDX)
CPPTEST_ITM_COMMUNICATION基于 ARM CoreSight ITM 单元的通信。需要 CMSIS 头文件。
CPPTEST_CUSTOM_COMMUNICATION为自定义实现启用空模板

如果使用提供的 Makefile 构建覆盖率运行时库,则可以使用[INSTALL_DIR]/bin/engine/coverage/runtime/channel目录中提供的 make 配置文件之一。

安装对自定义通信通道的支持

如果没有通信通道实现适合您的开发环境,则可以提供自定义实现。以下说明描述了如何自定义运行时库,以便它使用通信通道的自定义实现: 

  1. 复制 [INSTALL_DIR]/bin/engine/coverage/runtime/src/cpptest.c 并打开文件进行编辑。

  2. 找到 1.13 节“自定义通信实现。
    自定义通信实现部分包含用于四种不同方法的空模板:

    函数说明
    void cpptestInitializeStream(void)该函数负责初始化通信通道,例如创建并连接到套接字或初始化 UART 设备。
    void cpptestFinalizeStream(void)此函数负责完成通信通道。例如,它可能负责关闭 TCP/IP 套接字。

    int cpptestSendData(const char *data, unsigned size)

    该函数负责从数据缓冲区发送大小字节。
    void cpptestFlushData(void)此函数负责刷新数据。其含义取决于特定的运输类型。在某些实现中,它的应用可能有限。在这种情况下,应将其保留为空。
  3. 提供符合您的环境要求的这些方法的实现。
  4. 编译cpptest.c 并在编译命令行中添加以下宏定义
    -DCPPTEST_CUSTOM_COMMUNICATION
  5. 如果生成的目标文件不足,则可以进一步处理文件以满足您的需求(例如,创建共享库)。

切换多线程 API 支持

运行时库包含对多线程应用程序的支持。支持 POSIX,Windows 和 VxWorks API。您可以通过在cpptest.c编译期间将-D<MACRO>添加到编译命令行来启用对特定多线程 API 的支持。下表描述了多线程 API 支持控制宏的完整列表:

说明
CPPTEST_NO_THREADS空实现。覆盖率运行时不准备与多线程应用程序一起使用
CPPTEST_WINDOWS_THREADSWindows 多线程 API 实现
CPPTEST_UNIX_THREADSPOSIX 多线程 API 实现
CPPTEST_VXWORKS_THREADSVxWorks 多线程 API 实现

安装对自定义线程 API 的支持

如果将 C/C++test 的覆盖率引擎与不使用支持的多线程 API 的多线程应用程序一起使用,则可以自定义运行时库以与多线程 API 一起使用。需要执行以下步骤:

  1. 复制 [INSTALL_DIR]/bin/engine/coverage/runtime/src/cpptest.c 并打开文件进行编辑。

  2. 找到 2.5 节“自定义多线程实现”,
    自定义多线程实现一节包含用于两种不同方法的空模板:

    函数说明
    static int cpptestLock(void)此函数可确保覆盖率工具运行时库内的同步操作。如果线程锁定对运行时库服务的访问,则意味着正在进行原子操作,并且其他任何线程都不能使用运行时库服务。释放锁定后,其他线程可以使用运行时库服务
    static int cpptestLock(void)释放对运行时库服务的锁定。
  3. 提供与您的环境要求相匹配的方法的实现。

  4. 编译cpptest.c并在编译命令行中添加以下宏:
    -DCPPTEST_CUSTOM_THREADS

  5. 如果生成的目标文件不足,您可以进一步处理该文件以满足您的需要(例如,创建共享库)。

构建运行时库

C/C++test 附带了一个简单的生成文件(请参见Library Source Code Structure),该文件简化了构建运行时库的过程。但是在许多情况下,由于源代码已经针对构建过程进行了优化,因此不需要提供的 make 文件。始终唯一需要的步骤是主 cpptest.c 源文件的编译。生成的目标文件的任何其他处理将取决于特定的开发环境及其要求,例如将运行时库提供为共享库。

使用提供的生成文件构建运行时库

  1. 复制 <INSTALL_DIR>/bin/engine/coverage/runtime 给本地目录

  2. 如果需要修改编译标志(例如,添加交叉编译器或定义以强制执行运行时库重新配置),请在目标子目录中提供新的 make 配置文件。为方便起见,请复制现有目标配置文件之一并修改其内容以适合您的需求。
  3. 调用以下命令行以构建一个包含单个对象cpptest.<OBJ_EXT>的构建子目录,该目录可用于链接程序插桩。

    make TARGET_CFG=<target config file name> CHANNEL_FILE=<channel config file name>

    您的命令行可能类似于以下内容:

    make TARGET_CFG=gcc-static.mk CHANNEL_FILE=channel/unix-socket.mk

    或者,您可以提供信道类型:

    make TARGET_CFG=gcc-static.mk CHANNEL_TYPE=unix-socket
  4. 如果需要从共享库、动态链接库或任何其他类型的二进制文件链接到覆盖率运行时库,则需要为此自定义生成文件或设置自定义生成。

运行时库的用户构建

要设置覆盖率运行时库的用户构建,请执行以下步骤:

  1. 复制 cpptest.c 文件 <INSTALL_DIR>/bin/engine/coverage/runtime/src/cpptest.c 到您的首选位置

  2. 引入自定义运行时库中描述的任何自定义项。
  3. 设置您首选项的构建系统(例如 IAR Embedded Workbench 项目或任何其他类型的源代码构建器)。
  4. 修改编译标志以包含编译器包含具有以下值的标志(通常为 -I):-I <INSTALL_DIR>/bin/engine/coverage/runtime/include

  5. 添加任何必需的配置定义(通常为-D),例如:
    -DCPPTEST_FILE_COMMUNICATION -DCPPTEST_NO_THREADS
  6. 调用命令以运行构建器(例如,在 IDE 中选择 build 命令)。
  7. 找到生成的对象文件,并使用它与程序插桩链接。

排除代码覆盖率故障

如何显示覆盖率工作空间的诊断数据,包括错误和警告信息?

覆盖率工作空间保存插桩的代码和相应的静态覆盖率数据,以及插桩代码时生成的一些日志和配置文件。您可以使用-status 选项显示从覆盖率工作空间收集的诊断数据,包括错误和警告信息、文件数量等。或者,您可以使用 -status-verbose 来显示更详细的信息。

默认情况下,将扫描位于当前目录中的覆盖率工作空间以获取诊断数据。您可以使用 -workspace 选项配置不同的工作空间位置。

示例

cpptestcc -status
cpptestcc -status -workspace /path/to/workspace

cpptestcc -status-verbose
cpptestcc -status-verbose -workspace /path/to/workspace

如何将覆盖率工作空间的诊断数据发送给 Parasoft 技术支持?

您可以使用-techsupport 选项为覆盖率工作空间创建技术支持包。这将创建一个包含所有诊断数据的 .zip 文件,包括日志文件和无法成功插桩的文件的预处理源代码。

默认情况下,将扫描位于当前目录中的覆盖率工作空间以获取诊断数据。您可以使用-workspace 选项配置不同的工作空间位置。

示例

cpptestcc -techsupport
cpptestcc -techsupport -workspace /path/to/workspace

如果在生成应用程序覆盖率报告时未找到一个或多个源文件怎么办?

生成覆盖率报告时,C/C++test 要求所有针对代码覆盖率进行插桩的文件都在其原始位置可用。如果 C/C++test 在其原始位置找不到文件,则覆盖率报告是不完整的。在这种情况下,C/C++test 会显示一条带有丢失文件列表的警告消息。

要生成包含移动到不同位置的文件的覆盖率数据的覆盖率报告,您可以使用 CPPTEST_COVERAGE_SRC_ROOT 环境变量将原始路径映射到本地(当前)路径:

CPPTEST_COVERAGE_SRC_ROOT=/original/path1=/local/path1;/original/path2=/local/path2;...

示例

在下面的示例中, foo.cpp 文件被插桩用于覆盖率并移动到另一个位置。

  • 插桩文件的原始位置:/home/server/project-123/foo.cpp
  • 插桩文件的当前位置(生成报告时的位置):/home/devel/project/foo.cpp

生成包含 foo.cpp 文件的覆盖率数据的覆盖率报告:

  1. 使用 CPPTEST_COVERAGE_SRC_ROOT 环境变量定义路径映射,例如:
    > export CPPTEST_COVERAGE_SRC_ROOT=/home/server/project-123=/home/devel/project
  2. 生成覆盖率报告。

如果无法针对代码覆盖率插桩代码,如何使构建失败?

默认情况下,当无法成功插桩文件时,将在构建中使用该文件的原始(非插桩)版本并显示警告。如果一个或多个源文件无法针对覆盖率插桩,则要使构建失败,请使用 -disable-auto-recovery-mode选项。

示例

cpptestcc -disable-auto-recovery-mode [.。.]

如何收集构建期间多次编译的文件的覆盖率?

默认情况下,C/C++test 存储构建中每个源文件的一次编译的覆盖率数据。因此,在极少数情况下,在构建过程中多次编译源文件时,C/C++test 仅存储该源文件最后一次编译的覆盖率数据。这可能会导致生成报告时出现不完整的覆盖率报告并带有警告:“由于当前工作空间中缺少有关代码结构的某些信息,因此覆盖率报告可能不完整。”要为同一源文件存储多个覆盖数据变体(构建期间每次编译一个变体),请使用 -coverage-data-variants 选项。

确保同一源文件的不同编译不会引入冲突代码(例如,同一函数的不同变体)——这是不受支持的情况。

示例

cpptestcc -coverage-data-variants [.。.]
  • No labels