本主题介绍如何使用 C++test 来执行自动生成和/或用户定义的 C++test 或遗留 CppUnit 测试用例。

章节目录:

执行测试用例

C++test 可以运行并报告任何有效的 C++test 或遗留 CppUnit 测试用例的覆盖率信息。

gcc-nostdinc 选项处理

如果使用 GCC -nostdinc 选项,则需要执行以下步骤之一才能成功创建测试可执行文件:

  • 禁用数据源和流支持功能。这可以通过向编译器命令行添加以下选项来实现(通过项目属性> 构建设置): -DCPPTEST_DATA_SOURCES_ENABLED=0
    -DCPPTEST_DISABLE_STREAMS_REDIRECTION=1
  • 修改编译器命令行(在项目属性> 构建设置中)以包含头文件的标准系统目录。

运行测试用例执行的一般过程:

  1. 根据生成用于回归测试和异常发现的测试用例的说明生成测试用例。
  2. (可选)如果要为缺失的函数和变量定义自动生成桩函数,请运行内建的“Generate Stub”测试配置,或基于该测试配置的自定义测试配置。不建议用于定期执行的命令行测试
    • 有关如何生成桩函数的信息以及自定义 C++test 桩函数生成的说明,请参阅添加和修改桩函数
  3. (可选)如果要在执行测试之前检查自动生成的桩函数和测试是否兼容,可通过运行内建的“Build Test Executable”测试配置或基于该配置的自定义测试配置来执行试验构建。不建议用于定期执行的命令行测试。
  4. 使用内建的“Run Unit Tests”测试配置或基于该配置的自定义测试配置启动测试。

    提示 - 通过测试用例浏览器执行测试

    您可以直接在测试用例浏览器(Parasoft> 显示视图> 测试用例浏览器)执行测试。只需选择测试的资源(项目、文件夹、测试套件或测试用例)在测试用例浏览器中的节点,右键点击所选内容,然后从测试历史测试执行快捷菜单选择所需测试执行测试配置即可。

    已执行的测试将通过颜色编码来表示它们的结果状态。失败的测试使用红色标记。通过的测试使用绿色标记。

  5. 查看并响应测试用例执行结果。
  6. (可选)根据需要调整测试执行设置。

测试模板函数

C++test 对实例化函数模板和类模板的实例化成员执行单元测试。

详细信息请参阅模板函数支持

覆盖率详细信息

若要生成详细的覆盖率报告,在运行测试用例之前,应确保在选定的测试配置中启用生成详细的覆盖率报告 [覆盖率指标] 选项。打开测试配置,转到执行>运行时并选择该选项。

使用 cpptestcli 配置批处理模式回归测试执行

定期安排批处理模式回归测试可简单地执行内建的“Run Unit Tests”测试配置,或者基于该配置的自定义测试配置。

例如:

  • cpptestcli  -solution “C:\temp\*.sln” –config team://ExecuteTests -publish

有关配置批处理模式测试的更多详细信息,请参阅通过命令行界面进行测试

了解试验构建

C++test 可以执行测试可执行文件的试验构建,其中包括测试用例和用户桩函数,而无需执行测试。该特性可用于检查自动生成的桩函数和测试是否可以编译。即使被测试的项目中还没有任何测试用例,您也可以执行试验构建。 

推荐运行内建的“Build Test Executable”测试配置来执行试验构建。

了解和自定义自动桩函数生成

当您运行内建的“Generate Stubs”测试配置(或基于该配置的自定义测试配置)时,C++test 将自动为缺失的函数和变量定义生成可自定义的桩函数(或桩函数模板)。如执行测试用例 v2022.2 中所述,我们建议您先生成测试用例,在运行测试用例执行前,运行 Generate Stubs 测试配置,然后运行 Build Test Executable 测试配置。

当使用测试配置集运行测试来生成桩函数时,C++test 将在指定位置创建一个桩函数文件。如果 C++test 不能自动生成一个完整的桩函数定义,它将创建一个您可以自定义(通过输入相应的 return 语句、添加 include 指令等)的桩函数模板。在桩函数完成之前,桩函数模板将保存在桩函数文件中。

只有当没有其他定义(用户桩函数或原始桩函数)可用时,才会使用自动生成的桩函数。

可以根据添加和修改桩函数中的说明自定义自动生成的桩函数和桩函数模板。如果您自定义桩函数或桩函数模板,则需要重新运行分析来提示 C++test 使用自定义的设置。

创建自定义桩函数生成测试配置的步骤:

  1. 需通过选择 Parasoft> 测试配置打开测试配置面板。
  2. 右键点击内建> Unit Testing> Generate Stubs 测试配置,然后选择复制,一个新的 Generate Stubs 测试配置将被添加到用户自定义类别中。
  3. 选择用户自定义> Generate Stubs
  4. 打开执行> 符号选项卡。
  5. (可选)如果您不希望将生成的桩函数保存在默认位置(${project_loc}/stubs/autogenerated),可在自动生成的桩函数的输出位置字段输入位置。
  6. 点击应用,然后关闭

定义自定义测试单元

默认情况下,C++test 按以下方式计算被测文件(要测试的项目文件)和测试套件的列表:

  • 所有选择的测试套件以及与执行>常规选项卡的测试套件文件的搜索模式选项中指定的条件匹配的测试套件都将执行。如果测试套件文件使用 CPPTEST_CONTEXT and/or CPPTEST_INCLUDED_TO 宏,则相应的源文件和头文件将成为被测文件。
  • 所有选定的项目源文件和头文件都将成为被测文件。此外,C++test 将通过测试套件文件的搜索模式搜索 CPPTEST_CONTEXT 设置为这些被测试文件之一的测试套件文件;如果找到这样的测试套件文件,它们也将被执行。

如果希望 C++test 使用任何其他项目源文件解析来自被测试文件的原始定义,可以指定测试配置的使用来自附加的项目文件的符号选项(执行>符号选项卡)。此外,您还可以通过使用从以下位置找到的文件中的额外符号选项来指定使用哪些桩函数,并使用为每个被测试的上下文创建单独的测试可执行程序选项来指定是否希望 C++test 为每个上下文(单个源文件/头文件或项目)创建单独的测试可执行文件。

有关如何指定要使用的附加项目文件和桩函数,以及如何准备测试可执行文件的详细信息,请参阅符号选项卡

单独测试文件

在某些情况下,测试策略要求将单元测试应用于与其他相关组件隔离的代码。C++test 允许通过使用桩函数来执行这样的测试。

单独测试某个文件(在不同的“测试床”上,包括自定义和自动桩函数)的步骤:

  1. 选择要测试的文件。
  2. 使用“Unit Testing> File Scope> Run Unit Tests (File Scope)”内建测试配置运行测试。这通常会导致错误状态(详细信息显示在控制台视图中),因为 C++test 无法定位多个函数的定义。
  3. 通过以下方式提供缺失的函数或变量定义:
  4. 运行“Unit Testing> File Scope> Build Test Executable (File Scope)”内建测试配置,执行测试可执行文件的试验构建。建议采用这种方式确保所有必要的符号都被正确解析,并且不会因为自定义桩函数代码而引入编译错误。
  5. 运行内建“Unit Testing> File Scope> Run Unit Tests (File Scope)”来执行测试。这一次,运行应该成功完成。

忽略库和对象文件

单独测试文件时,您可能希望使用对象和库文件过滤器来避免测试指定的库和对象。在测试配置的忽略对象/库文件字段(执行> 符号选项卡),您可以指定以分号分隔的命令行选项模式列表。仅忽略链接器命令行中的选项。标准编译器库和通过 pragma 包含的库不会被过滤。

单独测试功能

您可以通过多种方式单独测试函数。本节描述了经常用于测试安全关键源代码的方法。这种测试的一个基本要求是被测试的函数源代码不应该被插桩模块修改。这是为了确保测试结果反映真实生产环境中的功能执行。这是为了确保测试结果反映真实生产环境中的功能执行。

要确保被测功能未插桩,您应该验证测试配置中的插桩设置:

  1. 打开测试配置,然后选择执行> 常规选项卡。
  2. 启用单元测试执行模式并点击执行细节部分中插桩模式字段的编辑

应只在测试源类别中启用以下功能:

    • 访问私有成员
    • 函数打桩(正确配置桩函数插桩模式)
    • 重命名 main() 函数

以下部分将提供有关配置打桩模式、管理每个测试套件配置的桩函数以及用于单独测试功能的测试可执行配置的其他详细信息。

配置桩函数插桩

您必须启用桩函数插桩并选择打桩模式,才能对被测代码使用桩函数。启用桩函数插桩会激活打桩引擎。选择打桩模式定义了应用桩函数调用的方式。有两种打桩模式可用:

  • 插桩函数调用
  • 插桩被打桩的函数(函数调用不修改)

还有一个启用 C++ 模板桩函数的选项。详细信息请参阅使用 C++模板的桩函数

以下示例说明了这些模式在调用桩函数或方法的方式上有何不同。 


/* Original definition of function to be stubbed */
int Func(void)
{
     // Function body
 }
/* tested function definition */
int testedFunction(void)
{
     int val = Func ();
     /* tested function body */
     return val;
}

 

下表显示了两种打桩模式的示例源代码的插桩版本:

插桩函数调用插桩被打桩的桩函数

 

/* Stub function definition */
int CppTest_Stub_StubbedFunc(void)
{ 
       // Stub body 
       return 0 
}
/* Original definition of stubbed function */
int Func(void)  
{
       // Function body 
} 
/* tested function definition */ 
int testedFunction(void)  
{ 
       int val = CppTest_Stub_StubbedFunc();
       /* tested function body */ 
       return val; 
}

 

/* Stub function definition */
int CppTest_Stub_StubbedFunc(void)
{ 
       // Stub body 
       return 0 
}
/* Original definition of stubbed function */
int Func(void)  
{
       return CppTest_Stub_StubbedFunc();
       // Function body removed 
} 
/* tested function definition */ 
int testedFunction(void)  
{ 
       int val = Func (); 
       /* tested function body */
       return val;  
}

当测试安全关键代码时,插桩打桩的函数模式通常是首选,因为它不会改变被测功能的主体。设置桩函数模式的步骤:

  1. 打开测试配置,然后选择执行> 常规选项卡。
  2. 点击插桩模式下拉菜单旁边的编辑并启用打桩模式

以这种方式配置插桩设置会存在一些限制:

  • 如果被测函数需要另一个函数的桩函数,那么在同一个测试会话中,被打桩的函数将变得不可测试(如果在被测试的源代码中定义)
  • 测试套件应该对具有相同桩函数配置的函数或方法的测试用例进行分组
  • 单个测试二进制不能包含具有冲突桩函数配置的测试套件。当一个测试套件假设在另一个测试套件中有一个被测函数的桩函数时便会出现这种情况

以下部分描述了如何处理这些限制。

配置测试可执行构建

  1. 打开测试配置并选择执行> 常规选项卡
  2. 在单元测试设置部分,启用用于将所选测试套件划分为测试可执行文件的规则








    以下设置可用:
    • 为所选内容创建测试可执行程序:所有非文件范围测试配置的默认值。
    • 为每个被测试的上下文创建单独的可执行程序:文件范围测试配置的默认设置。
    • 为每个测试套件创建单独的测试可执行程序:启用此选项可为您选择的每个测试套件创建单独的测试二进制。对于对测试用例进行分组的测试套件而言可能必须启用此选项,因为该情况下需要选择特定的桩函数,不能混合。
  3. 点击应用

管理特定测试套件的桩函数

单元测试策略有时要求组织为每个测试套件使用单独的桩函数集。这可以通过用于每个测试套件的专用测试配置来实现,或者最好通过直接在测试套件中指定期望的桩函数文件来实现。

为测试套件指定桩函数文件的步骤:

  1. 打开测试用例浏览器视图,双击测试套件
  2. 将所需的桩函数文件拖到附加的桩函数文件字段
    或者,您可以通过点击附加的桩函数文件字段右侧的文件浏览器按钮来浏览桩函数文件





















通过直接修改测试套件文件,也可以在不使用 GUI 的情况下将测试套件特定的桩函数文件添加到测试套件中。要将桩函数文件添加到测试套件中,在文本/代码编辑器中打开测试套件,并为每个桩函数文件插入以下宏。您还可以使用根目录路径来包含给定位置的所有桩函数。

CPPTEST_ADDITIONAL_STUB_FILES(<stub file path or root directory>);

可以在任何有效的 C/C++ 宏位置指定该宏,但必须将其添加到 cpptest.h 头文件之后。在测试套件级别指定的所有桩函数文件都附加到受测试配置设置影响的桩函数文件中。

执行单个测试用例

执行用户定义的测试用例集步骤:

  1. 选择要以下列方式之一执行的测试函数:
    • 选择测试用例浏览器中的测试用例。
    • 选择包含该测试用例的测试用例编辑器,并确保编辑器窗口处于“焦点中”(请参阅生成测试用例,获取有关使用测试用例编辑器的信息)
    • 在编辑器中为测试套件文件选择测试用例方法。
    • 选择相关的类视图节点。(您可以选择和执行不同测试套件中的测试用例。)

  2. 运行设置为执行测试用例的测试配置(例如,内建> Unit Testing> Run Unit Tests)。
    • 例如,右键点击所选内容,然后使用 Parasoft 快捷菜单运行首选测试配置。

从未解析的符号解析链接器错误

如果被测代码引用了其他文件中的符号,但 C++test 找不到这些符号,则 C++test 可能会报告链接器错误

查看哪些符号未解析的步骤:

  1. 启用测试配置中执行> 符号选项卡的执行早期检查,明确是否有潜在的链接器问题选项(详细信息请参阅执行选项卡设置 - 定义测试的执行方式)。
  2. 重新运行测试。

C++test 将在编译和链接阶段之前报告未解析的符号(未定义的函数)。查看未解析符号的步骤:

  • 打开桩函数视图,查找定义为 'N/A' 的符号。
  • 打开控制台视图,查找“无法为此函数配置桩函数 [函数]”消息。

有几种方法可以解析符号:

  • 自动为缺失的符号生成桩函数。详细信息请参阅了解和自定义自动桩函数生成
  • 如果在项目中定义了符号,则在测试配置的执行> 符号选项卡中启用使用来自附加的项目文件的符号选项并输入星号,然后重新运行测试。详细信息请参阅执行选项卡设置 - 定义测试的执行方式
  • 如果符号位于外部库中,应将外部库添加到链接器命令行,然后重新运行测试。

  • 除此之外,可以为缺失的函数提供用户定义的桩函数,然后重新运行测试。详细信息请参阅添加和修改桩函数

在测试执行期间使用调试器

请参阅在测试执行期间使用调试器

  • No labels