[CMake series] test with GoogleTest

Today, let's talk about the CMake test.

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

CMake provides us with complete test support. For example, it has a special module CTest.

CMake native test support

The tests that CMake natively supports are very simple. There are only two functions:

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

To put it simply, you need to implement an executable program that can accept input parameters. Use add_executable is OK. Regardless of the storage directory of the executable program, CMake will help you fill it in automatically.

enable_testing()

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)

Then, add_test after registering your test cases, the preparation is completed. After the compilation is completed, you can run the test cases in the following three ways.

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

Of course, you can also use CTest with CDash. CDash is a place where you can record test logs. You can go to https://my.cdash.org/index.php Generally speaking, after a large project, there will be a demand in this regard.

GoogleTest

In addition to the ctest above, we have powerful GoogleTest , which is a widely used C++ testing framework. Different from the above, GoogleTest needs to implement the test framework logic and parse parameters by itself. GoogleTest provides a test framework and Mock.

CMake also provides GoogleTest support:

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

It is used to replace add_test. By scanning the source code, it can read all the test cases, eliminating the problem of writing repeatedly on both sides. However, it has one problem: once the test case changes, it needs to run cmake again, otherwise it cannot know the changed test case.

Therefore, CMake has provided a new method 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]
)

Compared to gtest_add_tests, gtest_discover_tests achieves the purpose of registration by obtaining the test cases in the compiled executable program. Therefore, it is more robust. When the test cases change, there is no need to re run cmake (in fact, the principle is not magical. You can understand it by adding the --gtest\u list\u tests parameter to the compiled program runtime).

It is also very simple to use. In the case of GoogleTest dependency (if you don't know it, you need to review the contents of the previous two articles), you can use find_package introduces dependencies.

enable_testing()
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)

As for GoogleTest itself, that is to say, you can write test cases based on the documents (if you are interested, you can leave a message, and I will write another one if I have the opportunity). In addition, I previously wrote Tests in Golang We also mentioned how to write unit tests. In fact, the same principle is true here. Combined with Mock provided by GoogleTest, it can be very simple to write unit tests.

Ref

  1. Testing With CTest

Thanks for reading. This article was first published in Github issues: https://github.com/xizhibei/b... (Star and Watch strongly suggest: P); In addition, this article can also be read in my blog: https://blog.xizhibei.me/2020... .

This article adopts Signature - non-commercial use - shared in the same way (BY-NC-SA) License.

Tags: C++ unit testing Testing cmake

Posted by slionheart on Mon, 30 May 2022 19:52:48 +0530