How to pretty-print QString with GoogleTest framework?
Asked Answered
C

1

14

I am using the GoogleTest (GTest) framework in conjunction with a Qt5 application.

Whenever a test fails using a QString argument, the framework tries to print all the involved values. However, it cannot automatically handle foreign types (Qt5's QString in this case).

QString test = "Test";
ASSERT_EQ(test, "Value");

enter image description here

How can I get GoogleTest to pretty print QStrings automatically (= without having to manually convert them each time)?

Calipee answered 4/3, 2017 at 15:28 Comment(0)
C
22

The GoogleTest Guide explains how you can in general teach the framework to handle custom types.

In the end, the following code snippet is all that needs to be added for GoogleTest being able to work with QStrings:

QT_BEGIN_NAMESPACE
inline void PrintTo(const QString &qString, ::std::ostream *os)
{
    *os << qUtf8Printable(qString);
}
QT_END_NAMESPACE

This code MUST NOT be in the namespace of your test fixtures, but must be in the Qt namespace (or in general in the namespace where the type that should be pretty-printed is defined in). This code MUST also be viewable from all translation units where you call a GoogleTest assertion on that particular type, otherwise it will not get used (see comments).

As a result GoogleTest now pretty prints QStrings: enter image description here

You can of course also add some quotation marks to make it clearer that it comes from a QString:

*os << "\"" << qUtf8Printable(qString) << "\"";

Source: Webinar ICS Qt Test-Driven Development Using Google Test and Google Mock by Justin Noel, Senior Consulting Engineer

Calipee answered 4/3, 2017 at 15:28 Comment(7)
Some other tip: use qUtf8Printable if you also want print Unicode characters in your string (qPrintable converts to "local 8 bit", which may not be Unicode clean, especially on Windows); and go through QDebug (possibly acting on a QBuffer, hosting a QByteArray) if you want to print QStrings and escape the non-printable characters.Maxwell
I can NOT get this to work. The funny thing is that if I define two PrintTo functions (one taking a QString& and one taking a regular QString) I get a compiler error error C2668: 'PrintTo': ambiguous call to overloaded function could be 'void PrintTo(const QString,std::ostream *)' or 'void PrintTo(const QString &,std::ostream *)' however if I have just the one never seems to call it... what's the magic sauce?Mclemore
@Mclemore Did you ensure that PrintTo is not in your applications namespace? Apart from I don't know what the sauce might be. I just put those lines before my first fixture is declared in the same CPP file and it just works (QT 5.7 and latest GoogleTest).Calipee
@Gremwell, I was struggling with this also but the answer to this question solved it for me #24674015Lesleylesli
@Lesleylesli I had the same problem with the translation units. I have edited the answer accordingly.Curlpaper
This mechanism is super anoying because it is so fragile and name lookup can not really be debugged. I have a PrintTo() function for QColor and one for QString, both defined in the same compilation unit. The overload for QString is called, the overload for QColor is not called.I have no clue why.Ovalle
The relevant part of the Google Test documentation: google.github.io/googletest/…Woodcutter

© 2022 - 2024 — McMap. All rights reserved.