Cristian Adam

QtCreator and Google Test

In this article I will have a look on how to get started with Google Test libraries on Windows using Qt Creator for both MinGW and Visual C++.

I used the plural for Google Test libraries because there is Google Test – Google’s C++ test framework and also Google Mock – Google’s C++ mocking framework. They both are hosted on a single location on github.

Unfortunately the 2015 migration from Google Code to Github broke a lot of documentation search page links for Google Test, not to mention that the code snippets lost the syntax highlighting. disappointed

Here are the updated links for Google Test Primer and Google Mock for Dummies.

I will assume you have Qt Creator, CMake (and Ninja), MinGW and Visual C++ installed.

CMake setup

First step would be to get the master bundle zip package for both Google Mock and Google Test libraries. Then unpack the googletest-master.zip file into a directory e.g. Projects/GMock/Turtle.

Then create a CMakeLists.txt file with the following content:

cmake_minimum_required (VERSION 2.8)
project (turtle-test)

set (gtest_disable_pthreads on)

add_subdirectory (googletest-master)
config_compiler_and_linker()

add_executable (${PROJECT_NAME} mock_turtle_test.cpp)
target_link_libraries (${PROJECT_NAME} gtest gmock)

Looks simple enough. smile

add_subdirectory (googletest-master) will add the GMock and GTest include directories so we don’t have to.

set (gtest_disable_pthreads on) is needed for MinGW, otherwise we will get errors like:

C:/Projects/gmock/turtle/googletest-master/googletest/include/gtest/
internal/gtest-port.h:1782:3: error: 'AutoHandle' does not name a type

   AutoHandle thread_;

   ^

config_compiler_and_linker() is required for Visual C++, which otherwise we will have linking errors like:

gtest.lib(gtest-all.cc.obj) : error LNK2038: mismatch detected for 
'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 
'MDd_DynamicDebug' in mock_turtle_test.cpp.obj

Now all that is needed is the code for mock_turtle_test.cpp.

Code

I took the code for mock_turfle_test.cpp from the Google Mock for Dummies tutorial.

#include <gmock/gmock.h>

class Turtle
{
public:
    virtual ~Turtle() {};
    virtual void PenUp() = 0;
    virtual void PenDown() = 0;
    virtual void Forward(int distance) = 0;
    virtual void Turn(int degrees) = 0;
    virtual void GoTo(int x, int y) = 0;
    virtual int GetX() const = 0;
    virtual int GetY() const = 0;
};

class MockTurtle : public Turtle
{
public:
    MOCK_METHOD0(PenUp, void());
    MOCK_METHOD0(PenDown, void());
    MOCK_METHOD1(Forward, void(int distance));
    MOCK_METHOD1(Turn, void(int degrees));
    MOCK_METHOD2(GoTo, void(int x, int y));
    MOCK_CONST_METHOD0(GetX, int());
    MOCK_CONST_METHOD0(GetY, int());
};

class Painter
{
    Turtle* turtle;
public:
    Painter(Turtle* turtle) : turtle(turtle)
    {
    }

    bool DrawCircle(int x, int y, int)
    {
        turtle->GoTo(x, y);
        turtle->PenDown();

        return true;
    }
};

TEST(PainterTest, CanDrawSomething)
{
    MockTurtle turtle;

    // Set expectations
    EXPECT_CALL(turtle, GoTo(100, 50));
    EXPECT_CALL(turtle, PenDown());

    // Call sequence
    Painter painter(&turtle);

    EXPECT_TRUE(painter.DrawCircle(100, 50, 10));
}

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

The code mocks the Turtle interface and makes sure that Painter::DrawCircle will issue a call to Turtle::GoTo with 100 and 50 argument values, and a call to Turtle::PenDown().

Success

Open the CMakeLists.txt file with Qt Creator and compile and run the project! Here is a screen-shot from my machine:

Failure

But what happens if a tests fails? I have changed the argument from DrawCircle from 100 to 101. If I compile and run I will get the following:

We can see that the test has failed. But how can we go to the line that failed? Qt Creator has highlighted the error, but it can’t actually go to the line in question.

Test runner MinGW

Since Google Test will output the file and line that failed, we just need to make Qt Creator to parse the output.

We will achieve this by adding a simple line in CMakeLists.txt namely:

add_custom_target(unittest ${PROJECT_NAME})

Now we have a new target to the project named unittest which will run our test. But how do we run this target from Qt Creator? By typing cm (shorthand for cmake) in the locator bar!

After running the cm unittest the following happened:

We can see that in the bottom right the build progress bar is red and we got a list of issues. After double-clicking the first line we jumped to the line that failed sunglasses

Qt Creator should have treated this failure as an error and should have shown an error icon at line 50. I have opened up QTCREATORBUG-15505.

Test runner Visual C++

Compiling and running the failure test looks like this:

We can see that the error is being highlighted, which means that the output is parsed.

Now let’s try cm unittest:

The build is marked as red, but unfortunately the issues list is empty! disappointed

I have open up QTCREATORBUG-15506.

Hacking Google Test

I have noticed a difference between MinGW and Visual C++ GTest error lines:

Compiler Error Line
MinGW C:/Projects/gmock/turtle/mock_turtle_test.cpp:50: Failure
Visual C++ C:\Projects\gmock\turtle\mock_turtle_test.cpp(50): error:

By applying the following patch:

--- googletest-master/googletest/src/gtest.cc   2015-12-10 14:29:14.000000000 +0100
+++ googletest-master-errors/googletest/src/gtest.cc    2015-12-13 15:48:22.053251300 +0100
@@ -2835,9 +2835,9 @@
     case TestPartResult::kNonFatalFailure:
     case TestPartResult::kFatalFailure:
 #ifdef _MSC_VER
-      return "error: ";
+      return "error C0000: ";
 #else
-      return "Failure\n";
+      return "error: ";
 #endif
     default:
       return "Unknown result type";

I was able to get this for MinGW:

Respectively for Visual C++:

Conclusion

Using Google Test with Qt Creator is easy to setup and, with a bit of hacking, easy to use!

Comments