Today we’re going to talk about CMake tests.

However, we are still talking about C++ testing.

CMake provides excellent testing support, such as a dedicated module called CTest.

CMake native testing support

CMake’s native support for testing is simple, with only two functions:

enable_testing(a)add_test(NAME <name> COMMAND <command> [<arg>...]  [CONFIGURATIONS <config>...]  [WORKING_DIRECTORY <dir>] [COMMAND_EXPAND_LISTS])Copy the code

Simply put, you need to implement an executable program that accepts input parameters. Just use add_executable. CMake will make it automatically regardless of the executable directory.

enable_testing(a)add_executable(test_example test.cpp)
target_link_libraries(test_example example_lib)

add_test(NAME test_example1 COMMAND test_example --arg1=a --arg2=b)
add_test(NAME test_example2 COMMAND test_example --arg1=c --arg2=d)
Copy the code

Then, after registering your test case with add_test, you are ready to run the test case in one of the following three ways after compiling.

  • make test
  • cmake --build . --target test
  • ctest

Of course, you can also use CTest in conjunction with CDash, which is a place where you can log your tests. Check it out at my.cdash.org/index.php.

GoogleTest

In addition to ctest, we also have the powerful GoogleTest, which is the most widely used C++ testing framework today. Instead of implementing your own test framework logic and parsing parameters, GoogleTest provides testing frameworks and mocks.

CMake also provides support for GoogleTest:

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

It is designed to replace add_test. By scanning the source code, it can read all the test cases, eliminating the problem of duplicate writing on both sides, but it has a problem: whenever a test case changes, it needs to run cmake again, otherwise it has no way of knowing the changed test case.

Therefore, CMake has provided new methods since 3.10:

gtest_discover_tests(target [EXTRA_ARGS arg1...]  [WORKING_DIRECTORY dir] [TEST_PREFIX prefix] [TEST_SUFFIX suffix] [NO_PRETTY_TYPES] [NO_PRETTY_VALUES] [PROPERTIES name1 value1...]  [TEST_LIST var] [DISCOVERY_TIMEOUT seconds] )Copy the code

Compared to gtest_add_tests, gtest_DISCOVER_tests registers by taking test cases from the compiled executable, and is therefore much more robust and does not require rerunking cmake in the event of a test case change. You can use the –gtest_list_tests parameter when the compiled program is running.

It is also easy to use, in cases where GoogleTest dependencies exist (review the previous two articles if you don’t know), to introduce dependencies through find_package.

enable_testing(a)include(GoogleTest)
find_package(GTest 1.10.0)

add_executable(test test.cpp)
target_link_libraries(test GTest::gtest GTest::gtest_main GTest::gmock
                        GTest::gmock_main)
gtest_discover_tests(test)
Copy the code

As for the GoogleTest itself, it’s a matter of writing test cases by reading the documentation (leave a comment if you are interested, I’ll write another article if I have the chance). In addition, I mentioned how to write unit tests in the Golang test. In fact, the same principle applies here, combining the Mock provided by GoogleTest. We can write unit tests very easily.

Ref

  1. Testing With CTest

Github Issues: github.com/xizhibei/bl… (Star and Watch strongly suggest :P); This article also can read in my blog: blog. Xizhibei. Me / 2020/04/05 /… .

In this paperAttribution – Non-commercial Use – Shared in the same way (BY-NC-SA)Grant permission.