Introduction to GTest for C++ Unit Testing

Hello,

In this post, I am going to introduce the Google’s Test Framework for C++, GTest, for development of unit tests in C++.

Installation

To install GTest on Debian based Linux distros, I used apt:

sudo apt install libgtest-dev

This command will only install the sources into your src directory (for example: /usr/src/gtest), now you have to compile them with the tools: cmake and make:

cd /usr/src/gtest
sudo cmake CMakeLists.txt
sudo make

Then, finally, copy the generated binaries into your lib directory (for example: /usr/lib):

sudo cp libgtest.a libgtest_main.a /usr/lib

Example

This example will be a simplified calculator, named calc, for integer numbers with two operations: addition and subtraction.

NOTE: I have ignored the code comments to simplify the understanding, but remember to comment your code whenever necessary.

The header file calc.hpp:

// calc.hpp
#ifndef CALC_HPP_
#define CALC_HPP_

int add(int op1, int op2);
int sub(int op1, int op2);

#endif // CALC_HPP_

The implementation file calc.cpp:

// calc.cpp
#include "calc.hpp"

int add(int op1, int op2)
{
    return op1 + op2;
}

int sub(int op1, int op2)
{
    return op1 - op2;
}

And finally, the test file calc_test.cpp:

// calc_test.cpp
#include 
#include "calc.hpp"

TEST(CalcTest, Add)
{
 ASSERT_EQ(2, add(1, 1));
 ASSERT_EQ(5, add(3, 2));
 ASSERT_EQ(10, add(7, 3));
}

TEST(CalcTest, Sub)
{
 ASSERT_EQ(3, sub(5, 2));
 ASSERT_EQ(-10, sub(5, 15));
}

int main(int argc, char **argv)
{
 testing::InitGoogleTest(&argc, argv);
 return RUN_ALL_TESTS();
}

There are some new stuff from GTest here:

  1.  You must include gtest header file gtest/gtest.h (look at /usr/include/gtest for more information)
  2. The TEST macro is resposible for the creation of the test cases, where the first parameter is the test suite name and the second parameter is the specific test case name, which will be visible in the display information during execution
  3. The ASSERT_EQ, member of ASSERT_* group, defines the equality test for GTest and, based on this information, the framework verifies the success or failure of the tests and logs these information, aborting the test case when the test failed. You can use EXPECT_EQ if you want to continue the test case execution in the presence of a failure
  4. You prepare the GTest calling testing::InitGoogleTest passing a pointer to argc and the argv array (which is a pointer too)
  5. Then, you start GTest invoking RUN_ALL_TESTS()

Compilation

To compile the example, type the following command:

g++ -o calc_test calc_test.cpp calc.cpp -lgtest -lpthread

Note that you must link the code against the GTest (gtest) and the POSIX Thread (pthread) libs.

Running

To run the test suite, just type:

./calc_test

And the test runner will run each test suite and the result will be the execution summary:

gtest_result

Conclusion

During software development lifecycle is very important to develop test code to verify the correctness of production code, paving the way to improve the code quality, developer’s confidence when refactoring etc. In this context, using tools for automatic unit tests can help in the process, accelerating the test code development, execution and it can be integrated with Continuous Integration (CI) tools to be executed automatically for each change sent to the code server.

In the future’s posts, I will talk more about unit tests and the paradigm named Test Driver Development which changes the process: code -> test, to: test -> code

References

[1] https://github.com/google/googletest#Assertions
[2] https://www.eriksmistad.no/getting-started-with-google-test-on-ubuntu/

 

 

Advertisements

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s