8

I'm writing a c++ function to generate XML using TinyXML. I'd like to verify that a (relatively small) tree produced by my function gets turned into a string identical to a reference string.

// intended XML:
<element type="correct" />

It seems like the easiest way to do this comparison is to hardcode the reference string into the code:

//assignment
std::string intended = "<element type=\"correct\" />";

However, the backslashes to escape the quotes prevent the comparison from succeeding.

#include <tinyxml.h>
#include <string.h>
TiXmlElement test = TiXmlElement("element");
test.SetAttribute("type", "correct");
TiXmlPrinter printer;
test.Accept(&printer);
ASSERT_EQ(intended, printer.CStr()); // gtests macro

output:

Value of: printer.CStr()
Actual: "<element type="correct" />"
Expected: intended
Which is: "<element type=\"correct\" />"
tasteslikelemons
  • 397
  • 1
  • 2
  • 8
  • 5
    The backslashes wouldn't be part of the string with the code you've shown here. Something else must be going on. http://ideone.com/3H9PB7 – Mark Ransom Mar 12 '14 at 21:47
  • @tasteslikelemons You could try to `printf()` (or something similar) the value from `printer.CStr()` into another variable (or stream) to see if it then gets properly formatted to match your test case. – Philip Allgaier Mar 12 '14 at 21:52
  • Perhaps the strings are encoded differently. Try outputting boths strings (i.e. using std::cout) so that you can see exactly what `printer.CStr()` and `intended` look like. – pqvst Mar 12 '14 at 21:53
  • Strings won't compare equal if they have different number of spaces, one contains a `'\t'` where the other has a plain `' '`, or if one ends in `'\n'` and the other one doesn't. – vonbrand Mar 12 '14 at 21:56

1 Answers1

31

On the googletest Primer page I read that ASSERT_EQ() compares pointers. (which are only equal if they point to the same memory location). If you want to compare C strings, you should use ASSERT_STREQ().

ASSERT_STREQ(intended, printer.CStr());

If you want to compare std::string objects, you can do it this way1:

ASSERT_EQ(intended, printer.Str());

1 Contributed by johnfo through a comment.

stackprotector
  • 10,498
  • 4
  • 35
  • 64
wimh
  • 15,072
  • 6
  • 47
  • 98
  • 1
    Nice spot. The oddest thing is that the diagnostic output message escapes quotes in the expected but not the actual. – Alan Stokes Mar 12 '14 at 22:09
  • Perfect. In making this change I also noticed that ASSERT_STREQ takes pointers to cost char arrays--probably to prevent exactly the kinds of representation mismatches that were confusing me. – tasteslikelemons Mar 13 '14 at 14:16
  • 3
    I would mention the case insensitive assertions `ASSERT_STRCASEEQ` and `ASSERT_STRCASENE` even though this is out of the question's scope – VincentTellier May 23 '18 at 08:55
  • 2
    Apart from the suggestion that the strings are not actually correct, the obvious thing to do would be to use Str() instead of CStr() so: ASSERT_EQ(indended, printer.Str()); this will then do an std::string comparison, so == would be the expected behaviour. – johnfo Jun 16 '20 at 08:27
  • The documentation was moved to [assertions.md](https://github.com/google/googletest/blob/master/docs/reference/assertions.md). – stackprotector Sep 10 '21 at 11:19