Printing WTF::String in gtest assertion

236 views
Skip to first unread message

Yutaka Hirano

unread,
Jul 24, 2015, 10:03:27 AM7/24/15
to blink-dev
Hi,

In blink unittests (webkit_unit_tests), I often use EXPECT_EQ for WTF::String. Sadly when an assertion fails it generates a message which is not so useful, like

../../third_party/WebKit/Source/modules/fetch/BodyStreamBufferTest.cpp:45:
Failure Value of: String("World")
Actual: 8-byte object <98-56 4E-73 F1-16 00-00>
Expected: String("Hello")
Which is: 8-byte object <B0-57 4E-73 F1-16 00-00>

Please see failed tests in [1] for example.

I think the "<<" operator defined in wtf/testing/WTFTestHelpers.h is intended to solve this problem, but it doesn't work actually. When I use ::testing::PrintToString, it works (I added an assertion in [1] and it passes).

Strangely, in wtf_unittests, WTF::String is printed just as expected.

../../third_party/WebKit/Source/wtf/testing/WTFTestHelpersTest.cpp:55:
Failure Value of: String("World")
Actual: "World"
Expected: String("Hello")
Which is: "Hello"

Please see failed tests in [2] for example.

Does anyone know anything about this problem?
Thanks,

Sasha Bermeister

unread,
Jul 26, 2015, 10:19:50 PM7/26/15
to Yutaka Hirano, blink-dev
For debugging I sometimes use .ascii().data() to get a printable string, not sure if this is a good thing to use in a test though. This returns a C-style string which you can then use with EXPECT_STREQ, etc.

Yuta Kitamura

unread,
Jul 27, 2015, 12:54:17 AM7/27/15
to Sasha Bermeister, Yutaka Hirano, blink-dev
Add:

#include "wtf/testing/WTFTestHelpers.h"

Yutaka Hirano

unread,
Jul 27, 2015, 1:04:52 AM7/27/15
to Yuta Kitamura, Sasha Bermeister, blink-dev
For debugging I sometimes use .ascii().data() to get a printable string, not sure if this is a good thing to use in a test though. This returns a C-style string which you can then use with EXPECT_STREQ, etc.
Yeah, it would work but I would like to use EXPECT_EQ(WTF::String, WTF::String) if possible. If not, I would like to understand the reason.

Add:
#include "wtf/testing/WTFTestHelpers.h"
I included the header (https://codereview.chromium.org/1255803003/#ps100001) but it doesn't work.

Daniel Cheng

unread,
Jul 27, 2015, 2:18:20 PM7/27/15
to Yutaka Hirano, Yuta Kitamura, Sasha Bermeister, blink-dev

I poked at this a bit. It's very interesting because this works:

String testString("Hello");

std::cout << testString << "\n";  // Prints "Hello."

but this does not:

std::cout << ::testing::PrintToString(testString) << "\n";  // Prints 8-byte object <XX-XX XX-XX XX-XX XX-XX>

I asked around, and it turns out this is due to an ODR violation. Since WTF::String's operator<< isn't defined in the same header as WTF::String, there are two definitions of template<> DefaultPrintNonContainerTo(const WTF::String&, std::ostream*):

1. For tests that forget to #include "WTFTestHelpers.h", the definition of DefaultPrintNonContainerTo() uses gtest's fallback operator<<.
2. For tests that do include it, the definition uses the operator<< defined in WTFTestHelpers.h.

Since ODR is undefined behavior, it works sometimes and doesn't work other times. In this case, I think the solution is to define operator<< / PrintTo in the same header as WTF::String.

Daniel

Daniel Cheng

unread,
Jul 27, 2015, 3:35:36 PM7/27/15
to Yutaka Hirano, Yuta Kitamura, Sasha Bermeister, blink-dev
I've also filed https://crbug.com/514330 to fix these ODR violations.

Yuta Kitamura

unread,
Jul 27, 2015, 11:09:05 PM7/27/15
to Daniel Cheng, Yutaka Hirano, Sasha Bermeister, blink-dev
On Tue, Jul 28, 2015 at 3:18 AM, Daniel Cheng <dch...@chromium.org> wrote:

I poked at this a bit. It's very interesting because this works:

String testString("Hello");

std::cout << testString << "\n";  // Prints "Hello."

but this does not:

std::cout << ::testing::PrintToString(testString) << "\n";  // Prints 8-byte object <XX-XX XX-XX XX-XX XX-XX>

I asked around, and it turns out this is due to an ODR violation. Since WTF::String's operator<< isn't defined in the same header as WTF::String, there are two definitions of template<> DefaultPrintNonContainerTo(const WTF::String&, std::ostream*):

1. For tests that forget to #include "WTFTestHelpers.h", the definition of DefaultPrintNonContainerTo() uses gtest's fallback operator<<.
2. For tests that do include it, the definition uses the operator<< defined in WTFTestHelpers.h.

Since ODR is undefined behavior, it works sometimes and doesn't work other times. In this case, I think the solution is to define operator<< / PrintTo in the same header as WTF::String.


This is interesting. Thanks for stepping in!

Yutaka Hirano

unread,
Jul 28, 2015, 9:20:21 PM7/28/15
to Yuta Kitamura, Daniel Cheng, Sasha Bermeister, blink-dev
Thanks for the explanation and the fix!


Tim Ansell

unread,
Aug 11, 2015, 3:42:56 PM8/11/15
to Yutaka Hirano, Yuta Kitamura, Daniel Cheng, Sasha Bermeister, blink-dev
Just a FYI, a bunch of information on this is available at https://www.chromium.org/blink/unittesting#TOC-Pretty-Printers

It would be good if someone could update that page to include information about WTFTestHelpers.h and other stuff which was added since I wrote that page 2 years ago.

Tim 'mithro' Ansell

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Jeremy Roman

unread,
Aug 11, 2015, 3:47:27 PM8/11/15
to Tim Ansell, Yutaka Hirano, Yuta Kitamura, Daniel Cheng, Sasha Bermeister, blink-dev
Except don't include information about WTFTestHelpers.h, since that was removed two weeks ago. :)
Reply all
Reply to author
Forward
0 new messages