From 3f780c3fdeaee4f27866654bf02c8fb6ce34e269 Mon Sep 17 00:00:00 2001 From: Ottmar Zittlau Date: Fri, 2 May 2025 14:56:21 +0200 Subject: [PATCH] GoogleTest: Set DEF_SOURCE_LINE on tests if file and line are known This information is available when --gtest_output=json is supported, which it almost always is on GoogleTest >= 1.8.1. --- .../gtest-use-json-output-for-discovery.rst | 7 +++++ Modules/GoogleTestAddTests.cmake | 12 +++++++++ .../GoogleTest-DEF_SOURCE_LINE-stdout.txt | 8 ++++++ .../GoogleTest/GoogleTestDefSourceLine.cmake | 11 ++++++++ Tests/RunCMake/GoogleTest/RunCMakeTest.cmake | 27 +++++++++++++++++++ 5 files changed, 65 insertions(+) create mode 100644 Help/release/dev/gtest-use-json-output-for-discovery.rst create mode 100644 Tests/RunCMake/GoogleTest/GoogleTest-DEF_SOURCE_LINE-stdout.txt create mode 100644 Tests/RunCMake/GoogleTest/GoogleTestDefSourceLine.cmake diff --git a/Help/release/dev/gtest-use-json-output-for-discovery.rst b/Help/release/dev/gtest-use-json-output-for-discovery.rst new file mode 100644 index 0000000000..304b3c0848 --- /dev/null +++ b/Help/release/dev/gtest-use-json-output-for-discovery.rst @@ -0,0 +1,7 @@ +gtest-use-json-output-for-discovery +----------------------------------- + +* The :command:`gtest_discover_tests()` command from the :module:`GoogleTest` + module now sets the ``DEF_SOURCE_LINE`` test property for each discovered + test if gtest supports the ``--gtest_output=json`` option. This test + property is used by some IDEs to locate the source for each test. diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake index 7e131e5909..3061ed23c0 100644 --- a/Modules/GoogleTestAddTests.cmake +++ b/Modules/GoogleTestAddTests.cmake @@ -131,10 +131,16 @@ macro(write_test_to_file) endif() string(APPEND script ")\n") + set(maybe_LOCATION "") + if(NOT current_test_file STREQUAL "" AND NOT current_test_line STREQUAL "") + set(maybe_LOCATION DEF_SOURCE_LINE "${current_test_file}:${current_test_line}") + endif() + add_command(set_tests_properties "${guarded_testname}" PROPERTIES ${maybe_DISABLED} + ${maybe_LOCATION} WORKING_DIRECTORY "${arg_TEST_WORKING_DIR}" SKIP_REGULAR_EXPRESSION "\\[ SKIPPED \\]" ${arg_TEST_PROPERTIES} @@ -175,6 +181,10 @@ macro(parse_tests_from_output) string(REPLACE [[;]] [[\;]] output "${output}") string(REPLACE "\n" ";" output "${output}") + # Command line output doesn't contain information about the file and line number of the tests + set(current_test_file "") + set(current_test_line "") + # Parse output foreach(line ${output}) # Skip header @@ -265,6 +275,8 @@ macro(parse_tests_from_json json_file) endif() get_json_member_with_default(test_json "name" current_test_name) + get_json_member_with_default(test_json "file" current_test_file) + get_json_member_with_default(test_json "line" current_test_line) get_json_member_with_default(test_json "value_param" current_test_value_param) get_json_member_with_default(test_json "type_param" current_test_type_param) diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-DEF_SOURCE_LINE-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-DEF_SOURCE_LINE-stdout.txt new file mode 100644 index 0000000000..c42463b3af --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTest-DEF_SOURCE_LINE-stdout.txt @@ -0,0 +1,8 @@ +.*"tests" *:.* + *"name" *: *"basic.case_foo" *,.* + *"name" *: *"DEF_SOURCE_LINE", * + *"value" *: *"file1.cpp:1" * +.* + *"name" *: *"basic.case_bar" *,.* + *"name" *: *"DEF_SOURCE_LINE", * + *"value" *: *"file with spaces.cpp:2" * diff --git a/Tests/RunCMake/GoogleTest/GoogleTestDefSourceLine.cmake b/Tests/RunCMake/GoogleTest/GoogleTestDefSourceLine.cmake new file mode 100644 index 0000000000..19e41c0b16 --- /dev/null +++ b/Tests/RunCMake/GoogleTest/GoogleTestDefSourceLine.cmake @@ -0,0 +1,11 @@ +enable_language(CXX) +include(GoogleTest) + +enable_testing() + +include(xcode_sign_adhoc.cmake) + +add_executable(fake_gtest fake_gtest.cpp) +xcode_sign_adhoc(fake_gtest) + +gtest_discover_tests(fake_gtest) diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake index bef9c97dcf..122a409a38 100644 --- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake +++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake @@ -433,6 +433,32 @@ function(run_GoogleTest_LegacyParser) unset(ENV{NO_GTEST_JSON_OUTPUT}) endfunction() +function(run_GoogleTest_DEF_SOURCE_LINE) + # Use a single build tree for a few tests without cleaning. + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-DEF_SOURCE_LINE-build) + set(RunCMake_TEST_NO_CLEAN 1) + if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug) + endif() + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + + run_cmake(GoogleTestDefSourceLine) + + run_cmake_command(GoogleTest-DEF_SOURCE_LINE-build + ${CMAKE_COMMAND} + --build . + --config Debug + --target fake_gtest + ) + run_cmake_command(GoogleTest-DEF_SOURCE_LINE + ${CMAKE_CTEST_COMMAND} + -C Debug + -R "^basic\\.case_" + --show-only=json-v1 + ) +endfunction() + foreach(DISCOVERY_MODE POST_BUILD PRE_TEST) message(STATUS "Testing ${DISCOVERY_MODE} discovery mode via CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE global override...") run_GoogleTest(${DISCOVERY_MODE}) @@ -482,3 +508,4 @@ block(SCOPE_FOR VARIABLES) endblock() run_GoogleTest_LegacyParser() +run_GoogleTest_DEF_SOURCE_LINE()