From 0347de327f6cd545d54e1e96c92ba020f843a174 Mon Sep 17 00:00:00 2001 From: Stuart Schechter Date: Thu, 26 Sep 2019 23:17:15 +0000 Subject: [PATCH] I lost over a day trying to figure out why I couldn't set a working directory for tests. It turns out, you can't (at least for Visual Studio projects) if you used gtest_add_tests, but it works just fine using the more up to date gtest_discover_tests. This PR is written to facilitate two very common needs of testers: access to a working directory and the ability to include libraries (since, tests are often written to tests libraries.) Changes: Replace gtest_add_tests, which is outdated and causes problems (especially in Windows & visual studio) with gtest_discover_tests. Modified macros to show how working directories are set Add example that sets working directory and uses custom libraries. Add include(GoogleTest), which seems to be necessary on some platforms --- chapters/testing/googletest.md | 36 +++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/chapters/testing/googletest.md b/chapters/testing/googletest.md index 4c06bd0..b0ce79d 100644 --- a/chapters/testing/googletest.md +++ b/chapters/testing/googletest.md @@ -14,11 +14,16 @@ Then, in your main `CMakeLists.txt`: option(PACKAGE_TESTS "Build the tests" ON) if(PACKAGE_TESTS) enable_testing() + include(GoogleTest) add_subdirectory(tests) endif() ``` -I would recommend using something like `PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME` to set the default for the option, since this should only build by default if this is the current project. As mentioned before, you have to do the `enable_testing` in your main CMakeLists. Now, in your tests directory: +I would recommend using something like `PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME` to set the default for the `PACKAGE_TESTS` option, since this should only build by default if this is the current project. +As mentioned before, you have to do the `enable_testing` in your main CMakeLists. + + +Now, in your tests directory: ```cmake add_subdirectory("${PROJECT_SOURCE_DIR}/extern/googletest" "extern/googletest") @@ -49,9 +54,18 @@ Then, to add a test, I'd recommend the following macro: ```cmake macro(package_add_test TESTNAME) + # create an exectuable in which the tests will be stored add_executable(${TESTNAME} ${ARGN}) + # link the Google test infrastructure, mocking library, and a default main fuction to + # the test executable. Remove g_test_main if writing your own main function. target_link_libraries(${TESTNAME} gtest gmock gtest_main) - add_test(NAME ${TESTNAME} COMMAND ${TESTNAME}) + # gtest_discover_tests replaces gtest_add_tests, + # see https://cmake.org/cmake/help/v3.10/module/GoogleTest.html for more options to pass to it + gtest_discover_tests(${TESTNAME} + # set a working directory so your project root so that you can find test data via paths relative to the project root + WORKING_DIRECTORY ${PROJECT_DIR} + PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_DIR}" + ) set_target_properties(${TESTNAME} PROPERTIES FOLDER tests) endmacro() @@ -59,6 +73,22 @@ package_add_test(test1 test1.cpp) ``` This will allow you to quickly and simply add tests. Feel free to adjust to suit your needs. If you haven't seen it before, `ARGN` is "every argument after the listed ones". +Modify the macro to meet your needs. For example, if you're testing libraries and need to link in different libraries for different tests, you might use this: + +```cmake +macro(package_add_test_with_libraries TESTNAME FILES LIBRARIES TEST_WORKING_DIRECTORY) + add_executable(${TESTNAME} ${FILES}) + target_link_libraries(${TESTNAME} gtest gmock gtest_main ${LIBRARIES}) + gtest_discover_tests(${TESTNAME} + WORKING_DIRECTORY ${TEST_WORKING_DIRECTORY} + PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}" + ) + set_target_properties(${TESTNAME} PROPERTIES FOLDER tests) +endmacro() + +package_add_test_with_libraries(test1 test1.cpp lib_to_test "${PROJECT_DIR}/european-test-data/") +``` + ## Download method @@ -67,7 +97,7 @@ You can use the downloader in my [CMake helper repository][CLIUtils/cmake], usin This is a downloader for [GoogleTest], based on the excellent [DownloadProject] tool. Downloading a copy for each project is the recommended way to use GoogleTest (so much so, in fact, that they have disabled the automatic CMake install target), so this respects that design decision. This method downloads the project at configure time, so that IDE's correctly find the libraries. Using it is simple: ```cmake -cmake_minimum_required(VERSION 3.4) +cmake_minimum_required(VERSION 3.10) project(MyProject CXX) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)