Search code examples
c++cmakegoogletestcmakelists-options

How to run specific tests in CMake project with GoogleTest?


Project Overview:

I'm currently working on a C++ project that includes multiple things I'd like to test, and I'm using GoogleTest for unit testing. My project structure looks something like this:

project/
│
├── CMakeLists.txt
├── src/
│   ├── thing1.cpp
│   ├── thing2.cpp
│   └── other_thigns.cpp
└── tests/
    ├── CMakeLists.txt
    ├── thing1Tests.cpp
    ├── thing2Tests.cpp
    └── other_thingsTests.cpp

Current Situation:

I have set up my CMakeLists.txt in the tests directory to compile all test files into a single test executable and run them using GoogleTest's test discovery mechanism. Here's a simplified version of my CMakeLists.txt:

cmake_minimum_required(VERSION 3.16.3)

include(GoogleTest)

set(This tests)

set(Sources
    thing1.cpp
    thing2.cpp
    # Other test files
)

add_executable(${This} ${Sources})

target_link_libraries(${This} PRIVATE
    GTest::gtest_main
    Project
)

add_test (
    NAME ${This}
    COMMAND ${This}
)

gtest_discover_tests(${This})

Currently in VScode when I hit the "run" button at the bottom left, it runs all tests in the specified "Sources". As this project grows this would make wanting to test one part of it very tedious.

Desired Improvement:

I would like to enhance my testing setup by allowing the execution of specific *test.cpp files in my tests directory. This will provide better control over testing and facilitate targeted testing when making changes.

Ideally, it would be a command with options that take an argument and is able to filter which test I want to run using that argument.

Problem:

Currently I have not been able to find a way to be able to do this. This is one approach I tried adding to my CMakeList above:

# Define an option to specify the tests to run
option(RUN_SPECIFIC_TESTS "Run specific tests using --gtest_filter" OFF)

# Specify the tests to run using a command-line argument
if(RUN_SPECIFIC_TESTS)
    set(TEST_PREFIX "thing1") # Default test prefix, change as needed
    add_custom_target(run_specific_tests
        COMMAND ${This} --gtest_filter=${TEST_PREFIX}*
        DEPENDS ${This}
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    )
endif()

and the command I tried running was:

cmake --build . --target run_specific_tests -DRUN_SPECIFIC_TESTS=ON -DTEST_PREFIX=thing2

What I want to happen ideally:

I'm looking for a solution that enables me to specify which tests to run using a command-line argument or similar approach. For instance, I would like to execute only the "thing2" tests by running a command like the one above.

I need guidance on how to implement this solution effectively within my existing CMake and GoogleTest setup. Specifically, I need help modifying my CMakeLists.txt to allow the execution of specific tests based on command-line arguments. Any insights or examples on how to achieve this would be greatly appreciated.

Edit As others have pointed out, this question is similar to How to run specific test cases in GoogleTest. I tried to follow be I could as you can see in my Problem section. But as I am new to CMake I am probably missing something.


Solution

  • The question was unecessarily complicated I think. Instead of trying to run tests dependent on their *Tests.cpp I found the article: Advanced Options for GoogleTest. Which simply allowed me to use a option --gtest_filter= to filter by a tests suite name.

    This means a developer would need to know the suite name, and we would need to standardize how we name tests. But that is not a problem, and a code change was not necessary.

    If you are experieneing the same problem, the CMakeList.txt in "Current Situation" section is exactly what I have, and the commands to run specific tests are:

    • Run all tests: ./(YOUR TEST DIRECTORY) --gtest_filter=*
    • Run specific tests: ./(YOUR TEST DIRECTORY) --gtest_filter=(standard prefix suite name)*

    For example of running a specific test lets say in my thing2.cpp, a test in there could be:

    //thing2.cpp
    
    TEST(sample_test1_case, sample_test)
    {
        EXPECT_EQ(1, 1);
    }
    
    TEST(sample_test2_case, sample_test)
    {
        EXPECT_EQ(1, 1);
    }
    

    So the command to run this would be: ./(YOUR TEST DIRECTORY) --gtest_filter=sample_test*. This command would run both of those tests in thing2.cpp. If you just wanted to run one of those tests your command could look like: ./(YOUR TEST DIRECTORY) --gtest_filter=sample_test2* for example.

    With this approach you will just need to be more conciounce of how you name your tests suite names.