Pretty-Printing Output for QCOMPARE

We have created a custom class, say Person, and use it in a unit test.

void TestPerson::testEquality() { Person p1("Alice", 42); Person p2("Bob", 37); QCOMPARE(p1, p2); }

The unit test fails with this message.

FAIL!  : TestPerson::testEquality() Compared values are not the same Loc: [../QComparePrint/TestPerson.cpp(8)]

This message does not tell us how the two Person objects differ. We would like to see this message as we would see it for any type known to QCOMPARE.

FAIL!  : TestPerson::testEquality() Compared values are not the same Actual   (p1): "Person(Alice, 42)" Expected (p2): "Person(Bob, 37)" Loc: [../QComparePrint/TestPerson.cpp(16)]

How do we achieve such a pretty-printed output for QCOMPARE?

The solution turns out to be very simple. The QCOMPARE documentation gives the crucial hint.

QTest::toString()

Unfortunately, the documentation links to the first overload of QTest::toString(), which is irrelevant for our problem. If we don't give up and scroll down to the last overload of QTest::toString(), we will be rewarded. It suggests to overload toString() in the namespace of our class Person. Using the example from the documentation, we can quickly come up with our own overload of toString().

char *toString(const Person &p) { return QTest::toString("Person(" + p.firstName() + ", " + QString::number(p.age()) + ")"); }

Our overload assembles a formatted string of a Person object and passes this string to QTest::toString(const QString &value).

If we use QCOMPARE on Person objects only in one test class, we add our new toString() function to the source file of this test class. If we use it in several test classes, we put the function in a custom test library containing common test functionality.

You can find the example code on github.

Read next

Running Wayland Clients as Non-Root Users

Many embedded Linux systems use a Wayland compositor like Weston for window management. Qt applications act as Wayland clients. Weston composes the windows of the Qt applications into a single window and displays it on a screen. I still have