GoogleTest

在 3.9 版本中已添加。

此模块定义了有助于使用 Google Test 框架的函数。提供两种添加测试的机制。gtest_add_tests() 已沿用一段时间,最初通过 find_package(GTest)gtest_discover_tests() 在 CMake 3.10 中引入。

(较旧的) gtest_add_tests() 扫描源文件以识别测试。这通常有效,但有一些注意事项,包括在交叉编译环境中,并使得在测试上设置其他属性更加方便。但是,它对参数化测试的处理不太全面,并且它需要重新运行 CMake 以检测测试列表中的更改。

(较新的) gtest_discover_tests() 通过询问编译后的测试可执行文件以枚举其测试来发现测试。这更加健壮并提供了对参数化测试的更佳处理,并且在测试更改时无需重新运行 CMake。但是,它可能在交叉编译环境中不起作用,并且设置测试属性不太方便。

有关相应函数的更多详细信息,请参见其文档。

这两个命令都旨在替代使用 add_test() 来注册测试,并且将为每个 Google Test 测试用例创建一个单独的 CTest 测试。请注意,在某些情况下效率较低,因为同一实例中执行的多个测试用例无法共享常见的设置和清除逻辑。但是,它为 CTest 提供了更细粒度的通过/失败信息,通常被认为是有益的。默认情况下,CTest 测试名称与 Google Test 名称相同(即 suite.testcase);另请参见 TEST_PREFIXTEST_SUFFIX

gtest_add_tests

通过扫描源代码中是否含有 Google Test 宏,使用 CTest 自动添加测试

gtest_add_tests(TARGET target
                [SOURCES src1...]
                [EXTRA_ARGS args...]
                [WORKING_DIRECTORY dir]
                [TEST_PREFIX prefix]
                [TEST_SUFFIX suffix]
                [SKIP_DEPENDENCY]
                [TEST_LIST outVar]
)

gtest_add_tests 尝试通过扫描源文件来识别测试。虽然这通常有效,但它只使用基本的正则表达式匹配,这会被非典型的测试声明所破坏,并且不能完全“分割”参数化测试。此外,它要求重新运行 CMake 来发现任何新添加、已删除或已重命名的测试(默认情况下,这意味着在任何测试源文件发生更改时都会重新运行 CMake,但参见 SKIP_DEPENDENCY)。但是,它具有在 CMake 时间声明测试的优势,这在某种程度上简化了对测试设置附加属性,并且始终在交叉编译环境中运行。

选项有

TARGET target

指定 Google Test 可执行文件,其必须是已知的 CMake 可执行目标。运行测试时,CMake 替换已构建可执行文件的位置。

SOURCES src1...

提供时,只扫描列出的文件以找出测试用例。如果未给定此选项,将使用指定的 targetSOURCES 属性来获取源列表。

EXTRA_ARGS args...

任何要通过命令行传递给每个测试用例的额外参数。

版本 3.31 中已更改: args... 中的空值保留,请参见 CMP0178

WORKING_DIRECTORY dir

指定运行已发现的测试用例的目录。如果未提供此选项,则使用当前二进制目录。

TEST_PREFIX prefix

指定一个 prefix 以添加到每个已发现的测试用例名前。当多个调用同时使用相同的源文件时,这将很有用 gtest_add_test() 但不同 EXTRA_ARGS

TEST_SUFFIX suffix

类似于 TEST_PREFIXsuffix 附加到每个已发现的测试用例之后。这两个 TEST_PREFIXTEST_SUFFIX 可以指定。

SKIP_DEPENDENCY

通常,函数会创建一项依赖,这将导致在任何已扫描的源发生更改时重新运行 CMake。这是为了确保已发现的测试列表得到更新。如果不希望此行为(可能在实际编写测试用例时会发生这种情况),可使用此选项来防止添加依赖项。

TEST_LIST outVar

变量名为 outVar 将在调用范围内填充已发现的测试用例列表。这允许调用者执行诸如操作发现的测试的测试属性之类的操作。

3.31 版更改: TEST_LAUNCHERCROSSCOMPILING_EMULATOR 目标属性中的空值保留,请参见策略 CMP0178

使用示例

include(GoogleTest)
add_executable(FooTest FooUnitTest.cxx)
gtest_add_tests(TARGET      FooTest
                TEST_SUFFIX .noArgs
                TEST_LIST   noArgsTests
)
gtest_add_tests(TARGET      FooTest
                EXTRA_ARGS  --someArg someValue
                TEST_SUFFIX .withArgs
                TEST_LIST   withArgsTests
)
set_tests_properties(${noArgsTests}   PROPERTIES TIMEOUT 10)
set_tests_properties(${withArgsTests} PROPERTIES TIMEOUT 20)

为保持向后兼容性,还支持以下形式

gtest_add_tests(exe args files...)
exe

测试可执行文件的路径或 CMake 目标的名称。

args

传递给可执行文件的额外参数的 ;-list。整个列表必须作为单一参数传递。将其括在引号中,或传递 "" 以表示没有参数。

files...

要搜索测试和测试固定装置的源文件列表。或者,使用 AUTO 指定 exe 是要扫描其源的 CMake 可执行目标的名称。

include(GoogleTest)
set(FooTestArgs --foo 1 --bar 2)
add_executable(FooTest FooUnitTest.cxx)
gtest_add_tests(FooTest "${FooTestArgs}" AUTO)
gtest_discover_tests

通过向已编译的测试可执行文件查询可用的测试自动添加 CTest 测试

gtest_discover_tests(target
                     [EXTRA_ARGS args...]
                     [WORKING_DIRECTORY dir]
                     [TEST_PREFIX prefix]
                     [TEST_SUFFIX suffix]
                     [TEST_FILTER expr]
                     [NO_PRETTY_TYPES] [NO_PRETTY_VALUES]
                     [PROPERTIES name1 value1...]
                     [TEST_LIST var]
                     [DISCOVERY_TIMEOUT seconds]
                     [XML_OUTPUT_DIR dir]
                     [DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
                     [DISCOVERY_EXTRA_ARGS args...]
)

添加在 3.10 版中。

gtest_discover_tests() 在测试可执行文件上设置构建后或测试前命令,该命令通过使用 --gtest_list_tests 参数运行测试可执行文件来分析输出,从而生成测试列表。与 gtest_add_tests() 的 source parsing 方法相比,这确保了获得完整的测试列表,包括参数化测试的实例。由于测试发现发生在构建或测试期间,因此当测试列表发生更改时无需重新运行 CMake。但是,它要求正确设置 CROSSCOMPILING_EMULATOR 以便在交叉编译环境中运行。

此外,设置测试上的属性稍微不太方便,因为在 CMake 时间不可用测试。其他测试属性可通过 PROPERTIES 选项,分配给测试组作为一个整体。如果需要更精细的测试控件,可通过使用 TEST_INCLUDE_FILES 目录属性通过外部 CTest 脚本提供自定义内容。通过 <target>_TESTS 变量向此类脚本提供已发现的一组测试(请参阅下方的 TEST_LIST 选项以了解讨论和限制)。

选项有

目标

指定 Google Test 可执行文件,其必须是已知的 CMake 可执行目标。运行测试时,CMake 替换已构建可执行文件的位置。

EXTRA_ARGS args...

任何要通过命令行传递给每个测试用例的额外参数。

3.31 版本中更改: args... 中保留空值,请参阅 CMP0178

WORKING_DIRECTORY dir

指定运行已发现的测试用例的目录。如果未提供此选项,则使用当前二进制目录。

TEST_PREFIX prefix

指定一个 prefix 添加到每个发现的测试用例的名称之前。当在对 gtest_discover_tests() 的多个调用中使用同一测试可执行文件,但使用不同的 EXTRA_ARGS 时,这可能很有用。

TEST_SUFFIX suffix

类似于 TEST_PREFIXsuffix 附加到每个已发现的测试用例之后。这两个 TEST_PREFIXTEST_SUFFIX 可以指定。

TEST_FILTER expr

在 3.22 版本中添加。

在测试发现期间作为 --gtest_filter 参数传递的筛选表达式。请注意,表达式是基于通配符的格式,与 gtest 使用的原始测试名称进行匹配。对于类型或值参数化的测试,这些名称可能不同于 ctest 使用的可能进行美化打印的测试名称。

NO_PRETTY_TYPES

默认情况下,在 CTest 测试名称中,类型参数化测试的类型索引被实际类型名称替换。如果此行为不可取(例如:因为类型名称难以掌握),此选项将禁止此行为。

NO_PRETTY_VALUES

默认情况下,在 CTest 测试名称中,值参数化测试的值索引被实际值替换。如果此行为不可取(例如:因为值字符串难以掌握),此选项将禁止此行为。

PROPERTIES name1 value1...

指定对通过 gtest_discover_tests() 调用发现的所有测试设置的其他属性。

TEST_LIST var

在变量 var 中提供测试列表,而不是默认的 <target>_TESTS。当在对 gtest_discover_tests() 的多个调用中使用同一测试可执行文件时,这可能很有用。请注意,此变量仅在 CTest 中可用。

由于 CMake 解析规则的限制,名称中带有方括号的任何测试都会从存储在此变量中的测试列表中省略。但是,ctest 仍将定义和执行此类测试,就像普通测试一样。

DISCOVERY_TIMEOUT 数字

在 3.10.3 版本中添加。

指定 CMake 等待测试枚举可用测试的时间(以秒为单位)。如果测试时间超过此时间,发现(和您的构建)将失败。大多数测试可执行文件将非常快速地枚举其测试,但在某些特殊情况下,测试可能需要更长的超时时间。默认值为 5。另请参见 execute_process()TIMEOUT 选项。

注意

在 CMake 版本 3.10.1 和 3.10.2 中,此选项称为 TIMEOUT。这与 TIMEOUT 测试属性冲突,该属性是将使用 PROPERTIES 关键字设置的常见属性之一,通常会导致合法但意外的行为。在 CMake 3.10.3 中,将关键字更改为 DISCOVERY_TIMEOUT 以解决此问题。3.10.1 和 3.10.2 中 TIMEOUT 关键字的歧义行为尚未保留。

XML_OUTPUT_DIR 目录

在 3.18 版本中添加。

如果指定,此参数将与 --gtest_output=xml: 一起传递给测试可执行文件。实际文件名与测试目标相同,包括前缀和后缀。在并行测试执行时,应使用此方法代替 EXTRA_ARGS --gtest_output=xml 以避免编写 XML 结果输出时出现竞争条件。

DISCOVERY_MODE

在 3.18 版本中添加。

提供更多控制权,用于确定何时 gtest_discover_tests() 执行测试发现。默认情况下,POST_BUILD 设置一个构建后命令,以便在构建时执行测试发现。在某些场景中(例如交叉编译),这种 POST_BUILD 行为不可取。相比之下,PRE_TEST 延迟测试发现,直至执行测试之前。通过这种方式,测试发现发生在目标环境中,测试在此处更有机会找到合适的运行时依赖项。

如果不调用 gtest_discover_tests() 时传递 DISCOVERY_MODE,它会默认采用 CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE 变量的值。这提供了一种机制,用于全局选择首选的测试发现行为,而无需修改每个调用站点。

DISCOVERY_EXTRA_ARGS args...

在 3.31 版本中添加。

用于在发现命令的命令行上传递的任何额外参数。

在 3.29 版本中添加: 在测试发现和测试执行期间,会考虑 TEST_LAUNCHER 目标属性。

在 3.31 版本中更改: 保留了 TEST_LAUNCHERCROSSCOMPILING_EMULATOR 目标属性中的空值,请参见策略 CMP0178