Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This page presents the GoogleTest - testing framework made by Google. This tutorial covers the basics of testing with this framework. This page shows only the very basic and most needed GoogleTest functions and features, which should be a minimum set to start writing your own tests. For more information, see the GoogleTest documentation page.

  • GoogleTest is Google’s C++ testing and mocking framework.

    Table of Contents
    absoluteUrltrue

    Info
    titleThe source code can be find here:

    https://gitlab.eufus.psnc.eupl/bpogodzinskiach/ach-tutorials/-/tree/TDD-cpp/TDD-cpp/Introduction


    Info
    titleNote

    The project building guide will be presented on the next page in the section: 2. Build the project  - CMake

    After you finish that part of the tutorial, you can go back to the introductory page, build and compile your code, and run your tests. For preliminary purposes, it is enough to read the contents of this page.

     Test

Test concept

The framework supports Linux, Windows or Mac platforms and it supports any kind of tests, not just unit tests.

GoogleTest isolates the tests by running each of them on a different object.

A Test Plan is made up of one or more Test Suite that consist of multiple Test Cases.

Image Modified

The Test Cases use assertions to verify the correct operation of the code under test. Google's testing platform has built-in assertions that can be implemented in software. The test fails if it crash or the assertion fails, otherwise it will work.

...

 

 Possible exit status

A simple assertion is a statement that checks whether a condition is true and can produce three possible outcomes:

  • success
  • nonfatal failure
  • fatal failure (aborts the current function)

 Assertions types

Depending on the current test case, you may need to stop the test on the first assertion that fails or go to the end of the current test. This leads to the introduction of two main types of assertions built into the googletest framework, fatal and non-fatal:

Image Modified

The framework provides many macros for making simple assertions. Most of them can be divided into two types: ASSERT and EXPECT. The first is fatal, which means that failure at this stage results in an immediate fail of the test function. On the other hand, EXPECT continues execution and allows you to end the entire test function. To make it clearer what the difference between the ASSERT and EXPECT macro is, it is necessary to explain the structure of a simple test function. Before that, it is essential to introduce some basic 

...

assertions of the two types previously mentioned.

...

 Assertions macros

The assertion macro follows the given pattern: a generic assertion type, ASSERT or EXPECT, is used as a prefix. Then, an underscore character is placed next to the assertion name, followed by a specific assertion tag.

ASSERT_* EXPECT_*
The * (asterisks) in the above pattern indicates the place to put the character tag, eg EQ / NE / LT / LE / GT / GE.

Some of the simple and most useful assertions are summarized in the table below:

Fatal assertionNonfatal assertionVerifies
ASSERT_TRUE (condition);EXPECT_TRUE (condition);condition is true
ASSERT_FALSE (condition);EXPECT_FALSE (condition);condition is false
ASSERT_EQ(val1, val2);EXPECT_EQ(val1, val2);val1 == val2
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
ASSERT_STREQ(str1, str2);EXPECT_STREQ(str1str2);the two C strings str1 and str2 have the same contents
ASSERT_STRNE(str1, str2);EXPECT_STRNE(str1str2);the two C strings str1 and str2 have different contents
ASSERT_FLOAT_EQ(val1, val2);EXPECT_FLOAT_EQ(val1, val2);the two float values val1 and val2 are approximately equal,
to within 4 ULPs (unit of least precision) from each other
ASSERT_DOUBLE_EQ(val1, val2);EXPECT_DOUBLE_EQ(val1, val2);the two double values val1 and val2 are approximately equal,
to within 4 ULPs (unit of least precision) from each other

 Documentation about assertions

The Google's Test Framework provides a much larger collection of assertions that can be easily found in its official documentation.

Custom message

All assertion macros support streaming a custom failure message into them with the << operator, for example:

Code Block
languagecpp
EXPECT_TRUE(my_condition) << "My condition is not true";

When the test is run as a result of a test case failure, the custom message will be printed on the interface as shown in the example below:

Image Modified

Anything that can be streamed to an ostream can be streamed to an assertion macro–in particular, C strings and string objects.

 Running Tests

Proper use of the GoogleTest framework requires treating the tests themselves as a different project or sub-project.

Tests need to have only one main function for the whole sub-project mentioned above. It can be either a separate file that does not store the test functions, or a single file with all the tests and the main function at the end. The main function file must be in the main test directory (usually named tst) and can be named anything you want, but should be intuitive, such as main.cpp or run_tests.cpp.

Main function of the test run

The main function itself requires the following code:

Code Block
languagecpp
themeConfluence
linenumberstrue
#include "gtest/gtest.h"

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

All defined tests can be run with RUN_ALL_TESTS(), which returns 0 if all the tests are successful, or 1 otherwise. Note that RUN_ALL_TESTS() runs all tests in your link unit–they can be from different test suites, or even different source files.

The ::testing::InitGoogleTest() function parses the command line for GoogleTest flags. You must call this function before calling RUN_ALL_TESTS(), or the flags won’t be properly initialized.

 Simple Test example

A very basic test can be created with the TEST() macro, which helps define and name the test function. Such a function returns no value and only executes a test case. In the body of this function, various assertions, such as the ones mentioned above, can be used to validate the value. The test result is determined by the assertion result. A pass test can only be obtained if there has been no fatal or non-fatal test failure or the test has not crashed.

...

 

 Simple example of the basic test suite

The following is an example of the structure of the TEST () function:

Code Block
languagecpp
themeConfluence
linenumberstrue
TEST(TestSuiteName, TestName) {
  ASSERT_EQ(2+3, 5);
}

The arguments of the TEST() macro help determine the test function by test case. The first argument - TestSuiteName - as it says itself is the name of the test suite, a kind of grouping approach. The second argument is the name of the test (test case) within the test suite, which helps distinguish between specific tests. Both names must be correctly identified according to C++ practices and should not contain any underscores (_). The full name of the test consists of the name of the test suite and its individual name. Therefore, tests from different test suites can have identical case names, but not two identical tests in the same test suite.

...

A more comprehensive example

Let's expand the example above to have one more test suite containing two tests:

Code Block
languagecpp
themeConfluence
linenumberstrue
TEST(TestSuiteName, TestName) {
    ASSERT_EQ(2+3, 5);
}

TEST(TestSuiteName2, TestName1) {
    ASSERT_EQ(2+1, 3);
    EXPECT_EQ(2*1, 2);
}

TEST(TestSuiteName2, TestName2) {
    ASSERT_EQ(2-1, 1);
    EXPECT_EQ(2/1, 2);
}

 Test results

There are two suites of tests - TestSuiteName and TestSuiteName2, where the other has two tests - TestName1 and TestName2. All tests test slightly different test cases. The test results are as below:

Code Block
languagecpp
1: Note: Google Test filter = TestSuiteName.TestName
1: [==========] Running 1 test from 1 test suite.
1: [----------] 1 test from TestSuiteName
1: [ RUN      ] TestSuiteName.TestName
1: [       OK ] TestSuiteName.TestName (0 ms)
1: [----------] 1 test from TestSuiteName (0 ms total)
1: [==========] 1 test from 1 test suite ran. (0 ms total)
1: [  PASSED  ] 1 test.

2: Note: Google Test filter = TestSuiteName2.TestName1
2: [==========] Running 1 test from 1 test suite.
2: [----------] 1 test from TestSuiteName2
2: [ RUN      ] TestSuiteName2.TestName1
2: [       OK ] TestSuiteName2.TestName1 (0 ms)
2: [----------] 1 test from TestSuiteName2 (0 ms total)
2: [==========] 1 test from 1 test suite ran. (0 ms total)
2: [  PASSED  ] 1 test.

3: Note: Google Test filter = TestSuiteName2.TestName2
3: [==========] Running 1 test from 1 test suite.
3: [----------] 1 test from TestSuiteName2
3: [ RUN      ] TestSuiteName2.TestName2
3: [       OK ] TestSuiteName2.TestName2 (0 ms)
3: [----------] 1 test from TestSuiteName2 (0 ms total)
3: [==========] 1 test from 1 test suite ran. (0 ms total)
3: [  PASSED  ] 1 test.


Each test in the test suite is detected and run. While running, the framework informs that the test was run without crashing, and the result in this case is PASSED.