Building Google Test Framework with CMake

For those who does not know GTest (Google Test Framework), it is a simple way to make unit tests in C and C++ source code.

But what is an unit test?

In GTest Documentation you will find an in-depth description, but in general terms, one unit test consists in a specific test of one function of one source file from an application. It has basically an initialization phase to allows you to call the correspondent function. Then it comprises on make some sanity tests (assertions) to check if your code is behaving as expected.

How GTest works?

GTest provides some assertion macros which simplify the tests as the following numerical comparison assertions (there is also some macros for binary and string comparison):

Fatal assertion Nonfatal assertion Verifies
ASSERT_EQ(expected, actual); EXPECT_EQ(expected, actual); expected == actual
ASSERT_NE(val1, val2); EXPECT_NE(val1, val2); val1 != val2
ASSERT_LT(val1, val2); EXPECT_LT(val1, val2); val1 < val2
ASSERT_LE(val1, val2); EXPECT_LE(val1, val2); val1 <= val2
ASSERT_GT(val1, val2); EXPECT_GT(val1, val2); val1 > val2
ASSERT_GE(val1, val2); EXPECT_GE(val1, val2); val1 >= val2

How to build a simple example?

The first step is download the source code and build the GTest library, which can be performed using g++ compiler (replace $(GTEST_DIR) by the place of GTest directory):

wget http://googletest.googlecode.com/files/gtest-1.6.0.zip
unzip gtest-1.6.0.zip
g++ -I ${GTEST_DIR}/include -I ${GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc
ar -rv libgtest.a gtest-all.o

It will generates the libraries libgtest.a (which contains GTest binaries). Consider a simple unit test example of a C source code named test1.c:

#include <gtest/gtest.h>
TEST(MathTest, TwoPlusTwoEqualsFour) {
EXPECT_EQ(2 + 2, 4);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest( &argc, argv );
return RUN_ALL_TESTS();
}

To build it, it is necessary to defines the GTest headers directory (parameter includes dir -I), compile the source code and link it with the GTest library (libgtest.a) and pthread, as shown below (again, replace $(GTEST_DIR) by the GTest directory):

g++ -I ${GTEST_DIR}/include test1.c libgtest.a -lpthread -o test1

The call and the output is as follows:

./test1
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MathTest
[ RUN      ] MathTest.TwoPlusTwoEqualsFour
[       OK ] MathTest.TwoPlusTwoEqualsFour (0 ms)
[----------] 1 test from MathTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

How to build GTest samples?

Jointly with the GTest, it also comes some C++ unit test examples, found in the samples directory. You can build this examples using CMake a simpler and powerful tool to generate Makefiles. It can be installed using apt-get:

sudo apt-get install cmake

The CMake uses a configuration file named CMakeLists.txt. The common way to build a project with CMake is create a build directory, generate a Makefile using CMake and build it with make. One advantage of using CMake is that you separate the deploy from source code and can make the deploy in multiple places with the same CMake file.

cd gtest-1.6.0
mkdir build
cd build
cmake -Dgtest_build_samples=ON ..
make

Now you can execute all examples that comes GTest.

cd gtest-1.6.0/build
./sample1_unittest
./sample2_unittest
...
./sample10_unittest

How to build your own CMake?

A last tip is how to build a CMakeFile.txt for your project. Instead of use the CMake file provided by GTest, let’s make our own CMake to build the GTest’s sample 1 (Factorial test). The CMake file will requires to know where you unzip GTest, which can be performed through an environment variable named GTEST_ROOT (replace “/tmp/gtest-1.6.0” by the GTest directory).

GTEST_ROOT="/tmp/gtest-1.6.0"
export GTEST_ROOT

Then, creates a CMakeLists.txt with the content below:

cmake_minimum_required(VERSION 2.6)
project(sample1)
enable_testing()
find_package (Threads)
message(STATUS GTEST_ROOT=$ENV{GTEST_ROOT})
include_directories($ENV{GTEST_ROOT}/include)
link_directories($ENV{GTEST_ROOT}/mybuild)
add_executable(sample1 sample1.cc sample1_unittest.cc)
target_link_libraries(sample1 gtest gtest_main)
target_link_libraries(sample1 ${CMAKE_THREAD_LIBS_INIT})
add_test(NAME sample1 COMMAND sample1)

To build it you should repeat the same steps above:

mkdir build
cd build
cmake ..
make

The call and output of this example is as follows:

./sample1
[==========] Running 6 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 3 tests from FactorialTest
[ RUN      ] FactorialTest.Negative
[       OK ] FactorialTest.Negative (0 ms)
[ RUN      ] FactorialTest.Zero
[       OK ] FactorialTest.Zero (0 ms)
[ RUN      ] FactorialTest.Positive
[       OK ] FactorialTest.Positive (0 ms)
[----------] 3 tests from FactorialTest (0 ms total)

[----------] 3 tests from IsPrimeTest
[ RUN      ] IsPrimeTest.Negative
[       OK ] IsPrimeTest.Negative (0 ms)
[ RUN      ] IsPrimeTest.Trivial
[       OK ] IsPrimeTest.Trivial (0 ms)
[ RUN      ] IsPrimeTest.Positive
[       OK ] IsPrimeTest.Positive (0 ms)
[----------] 3 tests from IsPrimeTest (0 ms total)

[----------] Global test environment tear-down
[==========] 6 tests from 2 test cases ran. (1 ms total)
[  PASSED  ] 6 tests.

See ya!

7 Responses to Building Google Test Framework with CMake

  1. Bob says:

    I’m new to cmake and new to google test – this article was a great help. Thanks

  2. haitongz says:

    thx for post

  3. Frank says:

    It’s very useful information for me as for beginner. Thank you very much!

  4. Enrique says:

    Excellent post!!! This helped me a lot. Thank you!

  5. Udi says:

    Very good Introduction. Thanks🙂

  6. Craig Scott says:

    Complementing your post, if you want to integrate gtest into your build so that it is built as part of your project (but not having to add gtest’s source code to your own project), you may want to check out my recent blog article covering this approach here:

    http://crascit.com/2015/07/25/cmake-gtest/

    This avoids having to use a pre-built gtest and ensures your gtest is built with the same compiler and settings as the rest of your code. Hope this is useful!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: