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.eu/bpogodzinski/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.

    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. 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)

    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:

    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

    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

    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:

    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. 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. 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.

    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);
    }

    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.