mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
Merge topic 'gtest_add_tests'
6edd1806 GoogleTest: Expand capabilities of gtest_add_tests()
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !839
This commit is contained in:
@@ -2,4 +2,8 @@ ExtractGTestMacro
|
||||
-----------------
|
||||
|
||||
* A new :module:`GoogleTest` module was added to provide the
|
||||
``gtest_add_tests`` macro independently of the :module:`FindGTest` module.
|
||||
:command:`gtest_add_tests` function independently of the :module:`FindGTest`
|
||||
module. The function was also updated to support keyword arguments, with
|
||||
functionality expanded to allow a test name prefix and suffix to be
|
||||
specified, the dependency on the source files to be optional and the list of
|
||||
discovered test cases to be returned to the caller.
|
||||
|
||||
@@ -9,48 +9,162 @@ This module defines functions to help use the Google Test infrastructure.
|
||||
|
||||
.. command:: gtest_add_tests
|
||||
|
||||
Automatically add tests with CTest by scanning source code for Google test
|
||||
macros.
|
||||
Automatically add tests with CTest by scanning source code for Google Test
|
||||
macros::
|
||||
|
||||
::
|
||||
gtest_add_tests(TARGET target
|
||||
[SOURCES src1...]
|
||||
[EXTRA_ARGS arg1...]
|
||||
[WORKING_DIRECTORY dir]
|
||||
[TEST_PREFIX prefix]
|
||||
[TEST_SUFFIX suffix]
|
||||
[SKIP_DEPENDENCY]
|
||||
[TEST_LIST outVar]
|
||||
)
|
||||
|
||||
gtest_add_tests(<exe> <args> <files>...)
|
||||
``TARGET target``
|
||||
This must be a known CMake target. CMake will substitute the location of
|
||||
the built executable when running the test.
|
||||
|
||||
``<exe>``
|
||||
The path to the test executable.
|
||||
``<args>``
|
||||
``SOURCES src1...``
|
||||
When provided, only the listed files will be scanned for test cases. If
|
||||
this option is not given, the :prop_tgt:`SOURCES` property of the
|
||||
specified ``target`` will be used to obtain the list of sources.
|
||||
|
||||
``EXTRA_ARGS arg1...``
|
||||
Any extra arguments to pass on the command line to each test case.
|
||||
|
||||
``WORKING_DIRECTORY dir``
|
||||
Specifies the directory in which to run the discovered test cases. If this
|
||||
option is not provided, the current binary directory is used.
|
||||
|
||||
``TEST_PREFIX prefix``
|
||||
Allows the specified ``prefix`` to be prepended to the name of each
|
||||
discovered test case. This can be useful when the same source files are
|
||||
being used in multiple calls to ``gtest_add_test()`` but with different
|
||||
``EXTRA_ARGS``.
|
||||
|
||||
``TEST_SUFFIX suffix``
|
||||
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
|
||||
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` can be
|
||||
specified.
|
||||
|
||||
``SKIP_DEPENDENCY``
|
||||
Normally, the function creates a dependency which will cause CMake to be
|
||||
re-run if any of the sources being scanned are changed. This is to ensure
|
||||
that the list of discovered tests is updated. If this behavior is not
|
||||
desired (as may be the case while actually writing the test cases), this
|
||||
option can be used to prevent the dependency from being added.
|
||||
|
||||
``TEST_LIST outVar``
|
||||
The variable named by ``outVar`` will be populated in the calling scope
|
||||
with the list of discovered test cases. This allows the caller to do things
|
||||
like manipulate test properties of the discovered tests.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
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)
|
||||
|
||||
For backward compatibility reasons, the following form is also supported::
|
||||
|
||||
gtest_add_tests(exe args files...)
|
||||
|
||||
``exe``
|
||||
The path to the test executable or the name of a CMake target.
|
||||
``args``
|
||||
A ;-list of extra arguments to be passed to executable. The entire
|
||||
list must be passed as a single argument. Enclose it in quotes,
|
||||
or pass ``""`` for no arguments.
|
||||
``<files>...``
|
||||
``files...``
|
||||
A list of source files to search for tests and test fixtures.
|
||||
Alternatively, use ``AUTO`` to specify that ``<exe>`` is the name
|
||||
Alternatively, use ``AUTO`` to specify that ``exe`` is the name
|
||||
of a CMake executable target whose sources should be scanned.
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
.. code-block:: cmake
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
include(GoogleTest)
|
||||
set(FooTestArgs --foo 1 --bar 2)
|
||||
add_executable(FooTest FooUnitTest.cc)
|
||||
gtest_add_tests(FooTest "${FooTestArgs}" AUTO)
|
||||
include(GoogleTest)
|
||||
set(FooTestArgs --foo 1 --bar 2)
|
||||
add_executable(FooTest FooUnitTest.cxx)
|
||||
gtest_add_tests(FooTest "${FooTestArgs}" AUTO)
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
function(gtest_add_tests executable extra_args)
|
||||
if(NOT ARGN)
|
||||
message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS")
|
||||
function(gtest_add_tests)
|
||||
|
||||
if (ARGC LESS 1)
|
||||
message(FATAL_ERROR "No arguments supplied to gtest_add_tests()")
|
||||
endif()
|
||||
if(ARGN STREQUAL "AUTO")
|
||||
# obtain sources used for building that executable
|
||||
get_property(ARGN TARGET ${executable} PROPERTY SOURCES)
|
||||
|
||||
set(options
|
||||
SKIP_DEPENDENCY
|
||||
)
|
||||
set(oneValueArgs
|
||||
TARGET
|
||||
WORKING_DIRECTORY
|
||||
TEST_PREFIX
|
||||
TEST_SUFFIX
|
||||
TEST_LIST
|
||||
)
|
||||
set(multiValueArgs
|
||||
SOURCES
|
||||
EXTRA_ARGS
|
||||
)
|
||||
set(allKeywords ${options} ${oneValueArgs} ${multiValueArgs})
|
||||
|
||||
unset(sources)
|
||||
if("${ARGV0}" IN_LIST allKeywords)
|
||||
cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
set(autoAddSources YES)
|
||||
else()
|
||||
# Non-keyword syntax, convert to keyword form
|
||||
if (ARGC LESS 3)
|
||||
message(FATAL_ERROR "gtest_add_tests() without keyword options requires at least 3 arguments")
|
||||
endif()
|
||||
set(ARGS_TARGET "${ARGV0}")
|
||||
set(ARGS_EXTRA_ARGS "${ARGV1}")
|
||||
if(NOT "${ARGV2}" STREQUAL "AUTO")
|
||||
set(ARGS_SOURCES "${ARGV}")
|
||||
list(REMOVE_AT ARGS_SOURCES 0 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# The non-keyword syntax allows the first argument to be an arbitrary
|
||||
# executable rather than a target if source files are also provided. In all
|
||||
# other cases, both forms require a target.
|
||||
if(NOT TARGET "${ARGS_TARGET}" AND NOT ARGS_SOURCES)
|
||||
message(FATAL_ERROR "${ARGS_TARGET} does not define an existing CMake target")
|
||||
endif()
|
||||
if(NOT ARGS_WORKING_DIRECTORY)
|
||||
unset(workDir)
|
||||
else()
|
||||
set(workDir WORKING_DIRECTORY "${ARGS_WORKING_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
if(NOT ARGS_SOURCES)
|
||||
get_property(ARGS_SOURCES TARGET ${ARGS_TARGET} PROPERTY SOURCES)
|
||||
endif()
|
||||
|
||||
unset(testList)
|
||||
|
||||
set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
|
||||
set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
|
||||
foreach(source ${ARGN})
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source})
|
||||
|
||||
foreach(source IN LISTS ARGS_SOURCES)
|
||||
if(NOT ARGS_SKIP_DEPENDENCY)
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source})
|
||||
endif()
|
||||
file(READ "${source}" contents)
|
||||
string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents})
|
||||
foreach(hit ${found_tests})
|
||||
@@ -67,7 +181,16 @@ function(gtest_add_tests executable extra_args)
|
||||
message(WARNING "Could not parse GTest ${hit} for adding to CTest.")
|
||||
continue()
|
||||
endif()
|
||||
add_test(NAME ${test_name} COMMAND ${executable} --gtest_filter=${test_name} ${extra_args})
|
||||
add_test(NAME ${ARGS_TEST_PREFIX}${test_name}${ARGS_TEST_SUFFIX}
|
||||
${workDir}
|
||||
COMMAND ${ARGS_TARGET} --gtest_filter=${test_name} ${ARGS_EXTRA_ARGS}
|
||||
)
|
||||
list(APPEND testList ${ARGS_TEST_PREFIX}${test_name}${ARGS_TEST_SUFFIX})
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
if(ARGS_TEST_LIST)
|
||||
set(${ARGS_TEST_LIST} ${testList} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
@@ -1391,6 +1391,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
|
||||
|
||||
if(CMake_TEST_FindGTest)
|
||||
add_subdirectory(FindGTest)
|
||||
add_subdirectory(GoogleTest)
|
||||
endif()
|
||||
|
||||
if(CMake_TEST_FindICU)
|
||||
|
||||
10
Tests/GoogleTest/CMakeLists.txt
Normal file
10
Tests/GoogleTest/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
add_test(NAME GoogleTest.Test COMMAND
|
||||
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/GoogleTest/Test"
|
||||
"${CMake_BINARY_DIR}/Tests/GoogleTest/Test"
|
||||
${build_generator_args}
|
||||
--build-project TestGoogleTest
|
||||
--build-options ${build_options}
|
||||
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
|
||||
)
|
||||
82
Tests/GoogleTest/Test/CMakeLists.txt
Normal file
82
Tests/GoogleTest/Test/CMakeLists.txt
Normal file
@@ -0,0 +1,82 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
project(TestGoogleTest)
|
||||
include(CTest)
|
||||
|
||||
include(GoogleTest)
|
||||
|
||||
find_package(GTest REQUIRED)
|
||||
|
||||
add_executable(test_gtest1 main1.cxx)
|
||||
target_link_libraries(test_gtest1 GTest::GTest)
|
||||
|
||||
# Simple test of defaults
|
||||
gtest_add_tests(TARGET test_gtest1
|
||||
TEST_LIST testList
|
||||
)
|
||||
set(expectedTests
|
||||
GoogleTest.LinksAndRuns
|
||||
GoogleTest.ConditionalFail
|
||||
)
|
||||
if(NOT testList STREQUAL "${expectedTests}")
|
||||
message(FATAL_ERROR "Expected test list: ${expectedTests}
|
||||
Actual test list: ${testList}")
|
||||
endif()
|
||||
|
||||
|
||||
# Same target, different arguments, so use test prefix and suffix to
|
||||
# differentiate from the above test cases
|
||||
gtest_add_tests(TARGET test_gtest1
|
||||
TEST_LIST testList
|
||||
TEST_PREFIX "set2."
|
||||
TEST_SUFFIX ".foo"
|
||||
EXTRA_ARGS --forceFail
|
||||
)
|
||||
|
||||
set(expectedTests
|
||||
set2.GoogleTest.LinksAndRuns.foo
|
||||
set2.GoogleTest.ConditionalFail.foo
|
||||
)
|
||||
if(NOT testList STREQUAL "${expectedTests}")
|
||||
message(FATAL_ERROR "Expected test list: ${expectedTests}
|
||||
Actual test list: ${testList}")
|
||||
endif()
|
||||
|
||||
set_tests_properties(set2.GoogleTest.ConditionalFail.foo PROPERTIES WILL_FAIL YES)
|
||||
|
||||
|
||||
# Search specific sources to get the test list
|
||||
add_executable(test_gtest2 main2.cxx)
|
||||
target_link_libraries(test_gtest2 GTest::Main)
|
||||
gtest_add_tests(TARGET test_gtest2
|
||||
TEST_LIST testList
|
||||
SOURCES main2.h
|
||||
)
|
||||
set(expectedTests
|
||||
GoogleTest.SomethingElse
|
||||
)
|
||||
if(NOT testList STREQUAL "${expectedTests}")
|
||||
message(FATAL_ERROR "Expected test list: ${expectedTests}
|
||||
Actual test list: ${testList}")
|
||||
endif()
|
||||
|
||||
|
||||
# Non-keyword form, auto-find sources
|
||||
add_executable(test_gtest3 main3.cxx)
|
||||
target_link_libraries(test_gtest3 GTest::Main)
|
||||
gtest_add_tests(test_gtest3 "" AUTO)
|
||||
if(NOT TEST GoogleTest.Foo)
|
||||
message(FATAL_ERROR "Test case GoogleTest.Foo not defined")
|
||||
endif()
|
||||
if(NOT TEST GoogleTest.Bar)
|
||||
message(FATAL_ERROR "Test case GoogleTest.Bar not defined")
|
||||
endif()
|
||||
|
||||
|
||||
# Non-keyword form, explicitly specified sources. Allows a non-target to be
|
||||
# given for the executable.
|
||||
add_executable(test_gtest4 main4.cxx)
|
||||
target_link_libraries(test_gtest4 GTest::Main)
|
||||
gtest_add_tests($<TARGET_FILE:test_gtest4> "" main4.h)
|
||||
if(NOT TEST GoogleTest.NoKeywords)
|
||||
message(FATAL_ERROR "Test case GoogleTest.NoKeywords not defined")
|
||||
endif()
|
||||
30
Tests/GoogleTest/Test/main1.cxx
Normal file
30
Tests/GoogleTest/Test/main1.cxx
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
bool shouldFail = false;
|
||||
}
|
||||
|
||||
TEST(GoogleTest, LinksAndRuns)
|
||||
{
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
|
||||
TEST(GoogleTest, ConditionalFail)
|
||||
{
|
||||
ASSERT_FALSE(shouldFail);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
if (argc > 1) {
|
||||
if (argv[1] != std::string("--forceFail")) {
|
||||
throw "Unexpected argument";
|
||||
}
|
||||
shouldFail = true;
|
||||
}
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
1
Tests/GoogleTest/Test/main2.cxx
Normal file
1
Tests/GoogleTest/Test/main2.cxx
Normal file
@@ -0,0 +1 @@
|
||||
#include "main2.h"
|
||||
6
Tests/GoogleTest/Test/main2.h
Normal file
6
Tests/GoogleTest/Test/main2.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(GoogleTest, SomethingElse)
|
||||
{
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
11
Tests/GoogleTest/Test/main3.cxx
Normal file
11
Tests/GoogleTest/Test/main3.cxx
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(GoogleTest, Foo)
|
||||
{
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
|
||||
TEST(GoogleTest, Bar)
|
||||
{
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
1
Tests/GoogleTest/Test/main4.cxx
Normal file
1
Tests/GoogleTest/Test/main4.cxx
Normal file
@@ -0,0 +1 @@
|
||||
#include "main4.h"
|
||||
6
Tests/GoogleTest/Test/main4.h
Normal file
6
Tests/GoogleTest/Test/main4.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(GoogleTest, NoKeywords)
|
||||
{
|
||||
ASSERT_TRUE(true);
|
||||
}
|
||||
Reference in New Issue
Block a user