Google Test

Page Contents

Read The Docs!

Installing

To download the source files and install [Ref]:

sudo apt-get install libgtest-dev
cd /usr/src/gtest # Might also be /usr/src/googletest/googletest
sudo mkdir build
cd build
sudo cmake -DCMAKE_BUILD_TYPE=RELEASE ..
sudo make
sudo cp libg* /usr/lib
cd ..
sudo rm -fr build

Skeleton main()

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

Basic Test Structure

Simple Tests

When there is nothing to do to prepare for your tests, i.e., no setup or tear down, just use the TEST() macro to define the tests:

TEST(TestCaseName, ThisTestName) {
    ...
}

Test Fixtures

If you have some preparation for each test, i.e., you require some test setup and tear down, then use the TEST_F() macro. To use this macro you need to create a test-fixture object that inherits from public testing::Test:

// Class is created for each test and destroyed after
class MyTestFixture : public testing::Test {
protected:

    MyTestFixture() {
        // Can do setup here too
    }

    ~MyTestFixture() {
        // Can do tear down here too
    }

    // Called before each test is run
    virtual void SetUp() override {
        ...
    }

    // Called after each test. Don't neeed to define if no tear down required.
    virtual void TearDown() override {
        ...
    }

    int m_dummy;
};

...

TEST_F(MyTestFixture, ThisTestName)
{
    // You can refer to all the members and functions in the class MyTestFixture here directly.
    // For example:
    std::cout << "Dummy is " << m_dummy << "\n";
}

Parameterised Tests

Replace for loops that repeat a test over a data range with parameterised tests. Loops stop each test case being independent as when one fails the loop stops so that latter cases are not tested.

INSTANTIATE_TEST_CASE_P( // OR INSTANTIATE_TEST_SUITE_P??
    MyTests,
    MyParameterizedTestFixture,
    ::testing::Values(
            1, 2, 3, 4, 5,...
    )
);

class MyParameterizedTestFixture : public ::testing::TestWithParam<int> {
    ...
};

TEST_P(MyParameterizedTestFixture, SomeTestCase) {
    int test_value = GetParam();
    ...
    ASSERT_TRUE(some_predicate(..., test_value, ...));
    ...
}

To pass multiple values just used std::make_tuple for the data items and then use std::get<n>(GetParam()), where n is the index into the parameter tuple.

Basic Test Assertions

The test macros are ASSERT_* or EXPECT_*. The former is a fatal error and returns from the current function and the latter prints out a warning, continues in the current function and the error is logged only after it completes.

All the macros return a stream-like object that you can stream a message to that will be printed out on error. For example:

ASSERT_GT(1,2) << "1 is not greater than 2";

Also note that when test macros fail, they only abort the current function, not the entire test, so if you call functions from your TEST[_F] macro-function and the sub function errors, your main test function will still continue. See Google's advanced guide for more info. Probably the easiest solution is to wrap subroutine calls with ASSERT_NO_FATAL_FAILURE().

Here are some common test macros:

Check booleans: ASSERT_(TRUE|FALSE)
Check numbers: ASSERT_(EQ|NE|LT|LE|GT|GE)
Check C-style strings: ASSERT_STR(EQ|NE) and ASSERT_STRCASE(EQ|NE) to ignore case.
Check floats: ASSERT_NEAR or ASSERT_(FLOAT|DOUBLE)_EQ.
Check exceptions: ASSERT_THROW or ASSERT_(ANY|NO)THROW.
Eg: ASSERT_THROW(Foo(5), bar_exception);
Eg: EXPECT_NO_THROW({ .. body of code... });
Matchers:

These make use of GMock matchers, so you must include "gmock/gmock.h" in your test code.

(ASSERT|EXPECT)_THAT(value, matcher)

Examples:

EXPECT_THAT(Foo(), StartsWith("Hello"));
EXPECT_THAT(Bar(), MatchesRegex("Line \\d+"));
ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10)));

Passing Arguments To Your Test Program

When you compile your Google Test application it includes code that parses the command line options to enable things like filtering tests etc. So, how then, do you pass command line options through to your test code?

The answer is that after parsing all the Google Test relevant command line options, they are removed from argv and argc is updated appropriately so that in your main() function you can just parse argv. The remaining arguments will be all those that Google Test didn't recognise.

To parse command line options there are several options including Boost, getopt(), or to roll-your-own parser [Ref]. Some examples, taken from the reference and modified slightly:

static std::string getCmdOption(char **begin, char **end, const std::string &option)
{
    char **itr = std::find(begin, end, option);
    if (itr != end && ++itr != end)
    {
        return std::string(*itr);
    }
    return std::string();
}
static bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
    return std::find(begin, end, option) != end;
}

Often, if all or many tests need to query your own test options it can be a nice idea to base all of your tests off a base class that inherits from ::testing::Test and contains functions to get any options. E.g. base your test classes on this:

#include <gtest/gtest.h>

...

class TestBase : public ::testing::Test
{
public:
    static void Initialise(int exOpt1, const std::string ∓exOpt2)
    {
        exampleCommandLineOption1 = exOpt1;
        exampleCommandLineOption2 = exOpt2;
    }

    static int GetExampleCommandLineOption1(void)
    {
        return exampleCommandLineOption1;
    }

    ...

private:
    static int exampleCommandLineOption1;
    static std::string exampleCommandLineOption2;
};

Just call the Initialise() function before you call RUN_ALL_TESTS() and all your test classes will have access to the command line options you parsed.

Filtering Tests

To list your tests run with --gtest_list_tests.

Just run your test executable with the --gtest_filter=test-name(s) option. The filter accepts file-globbing syntax so you can use, for example, --gtest_filter=my_new_test* to run all tests who's name is prefixed with "my_new_test".

Scoped Traces

GTest has a useful macro SCOPED_TRACE(streamable). It is useful because it creates a stack of messages that will automatically printed out with any error trace. This can be handy to a) see the path through the test that failed and b) see loop iteration numbers that fail.

One useful little macro follows. SCIPED_TRACE accepts a streamable object but sometimes you may want to build up a string, so the following can be used.

#define SCOPED_TRACE_STR(x) \
    SCOPED_TRACE( \
        static_cast<std::stringstream &>( \
            (std::stringstream().flush() << x) \
        ).str())