Adding Unit Tests to Advanced CMake Projects

This tutorial shows how to add unit test targets to Advanced CMake projects. Unlike the Make-based, or MSBuild-based projects that are limited to one target per project, Advanced CMake projects can contain multiple targets (i.e. executables and libraries). This greatly simplifies the project structure:

  • Common settings, such as toolchain, deployment or debug settings, are defined on the project level.
  • Targets (libraries and executables) are defined using concise CMake statements without duplicating any project-level settings.

We will start with creating a basic Raspberry Pi executable built with a cross-toolchain, and will then show how to move testable logic out of it into a static library, and how to add another target that will contain unit tests for that library.

Before you begin, install VisualGDB 5.5R3 or later.

  1. Start Visual Studio and open the VisualGDB Linux Project Wizard:
  2. Enter the name and location of the project:
  3. The easiest way to create a unit test project would be to pick “Unit Test” on the “Project Type” page of VisualGDB Project Wizard, however in this tutorial we will demonstrate how to add unit tests to existing code, so we will start with creating a regular project instead:
  4. Select how you would like to build the project. Starting from VisualGDB 5.5R3, unit tests are supported for both cross-compiled projects and projects built directly on the target (including projects accessed directly via SSH):
  5. Press “Finish” to create the project. Once it is created, add a new source file to the main executable:
  6. Add the following function in the newly added source file:
    #include "Sum.h"
    int sum(int a, int b)
        return a + b;

    Then add a declaration for this function to Sum.h:

    #pragma once
    int sum(int a, int b);

  7. Include the Sum.h file and call sum() from the main source file:Now we have created a basic executable consisting of a testable sum() function and the main() function calling it. Verify that the project builds successfully by selecting Build->Build Solution.
  8. Now we will show how to split the project into a main application, testable library, and a unit test executable. Open VisualGDB Project Properties and reference the GoogleTest framework via the Unit Tests page:
  9. VisualGDB will automatically import the framework into the project as a separate target. Note that main CMakeLists.txt file will not explicitly declare the framework t target. Instead, it will call the find_test_framework() function defined in the toolchain file, that will create the library. When a newer version of the test framework is released, VisualGDB will update the toolchain file, without changing the CMakeLists.txt file:
  10. Right-click on the project node in Solution Explorer (with CMake icon) and select Add->New Item:
  11. Add a new executable called TestExecutable:
  12. Then add a new library called MathLibrary. Move the Sum.cpp and Sum.h files from the main executable to MathLibrary by either editing CMakeLists.txt directly, or using the File->Add Existing command in Solution Explorer:
  13. Reference MathLibrary from the main executable. Reference both MathLibrary and TESTFW (internal name for the test framework target) from TestExecutable:
  14. Update the TestExecutable.cpp file to define one or more unit tests, and also to call the test framework:
    #include <stdio.h>
    #include <gtest/gtest.h>
    #include "Sum.h"
    int main(int argc, char *argv[])
        testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
    TEST(DemoTestGroup, SumTest)
        ASSERT_EQ(3, sum(1, 2));
        ASSERT_EQ(-4, sum(1, -5));
        ASSERT_EQ(4, sum(-1, 5));

    If you are not familiar with GoogleTest or CppUTest, try creating a new unit test project from scratch as shown in this tutorial and copy the main() function and some sample tests from it.

  15. Once you build the project, the test will appear in the Test Explorer window:
  16. You can run or debug tests via Test Explorer. If your project contains multiple test executables, VisualGDB will automatically discover all of them and will let you run arbitrary subsets of these tests: You can also run tests programmatically and generate XML report files. See our Embedded Unit Test tutorial for more details.