...

/

Testing and Program Analysis

Testing and Program Analysis

Let's learn program testing and analysis requirements for the course project using CMake.

Program analysis and testing go hand in hand to assure the quality of our solutions. For example, running Valgrind becomes more consistent when test code is used. For this reason, we'll configure those two things together.  The following figure illustrates the execution flow and files needed to set them up (a few snippets will be added to the src directory):

Press + to interact
Files used to enable testing and program analysis
Files used to enable testing and program analysis

As we already know, tests live in the test directory, and their listfile gets executed from the top-level listfile with the add_subdirectory() command. Let's see what's inside:

Press + to interact
include(Testing)
add_subdirectory(calc)
add_subdirectory(calc_console)

Testing utilities defined in the Testing module are included at this level to allow both target groups (from the calc and the calc_console directories) to use them:

Press + to interact
enable_testing()
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)
# For Windows: Prevent overriding the parent project's
# compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
option(INSTALL_GMOCK "Install GMock" OFF)
option(INSTALL_GTEST "Install GTest" OFF)
FetchContent_MakeAvailable(googletest)
...

We enabled testing and included the FetchContent module to get GTest and GMock. We're not really using GMock in this project, but these two frameworks are bundled in a single repository, so we need to configure GMock as well. The highlighted part of this configuration disengages the installation of both frameworks from the installation of our project (by setting the appropriate option() to OFF).

Next, we need to create a function that enables the thorough testing of business targets. We'll keep it in the same file:

Press + to interact
...
include(GoogleTest)
include(Coverage)
include(Memcheck)
macro(AddTests target)
target_link_libraries(${target} PRIVATE gtest_main gmock)
gtest_discover_tests(${target})
AddCoverage(${target})
AddMemcheck(${target})
endmacro()

Here, we first include the necessary modules: GoogleTest is bundled with CMake, but Coverage and Memcheck will be written by us. We then provide an AddTests macro, which will prepare a target for testing, instrument coverage, and memory checking. Let's see how it works in detail. ...