Domanda

Does CPPUnit have any functionality that would allow me to do printf-style assertions? For example:

CPPUNIT_ASSERT("Actual size: %d", p->GetSize(), p->GetSize() == 0);

I know this is not a valid CPPUNIT_ASSERT - I am just using this as an example.

I found CPPUNIT_ASSERT_MESSAGE(message,condition) which takes a string and then the condition to evaluate but no luck getting the value into the assert.

È stato utile?

Soluzione

You should be able to do something like this:

#define CPPUNIT_ASSERT_STREAM(MSG, CONDITION) \
    do { \
        std::ostringstream oss; \
        CPPUNIT_ASSERT_MESSAGE(\
            static_cast<std::ostringstream &>(oss << MSG).str(), \
            CONDITION); \
    } while (0)

CPPUNIT_ASSERT_STREAM("Actual size: " << p->GetSize(), p->GetSize() == 0);

The above macro can also be combined with Boost.format:

CPPUNIT_ASSERT_STREAM(boost::format("Actual size: %d") % p->GetSize(),
                      p->GetSize() == 0);

Altri suggerimenti

I use selfdefined assert to print all needed info:

#ifdef NDEBUG
#define ASSERT(v, msg)
#else
#define ASSERT(v, msg) \
if (v) {} else { \
  std::cerr << __FILE__ << ":" << __LINE__ << " assertion failed: " \
            << #v << " = " << (v) << "\n" << msg << std::endl; \
  abort(); \
}
#endif

To use:

#include <iostream>
...
ASSERT( p->GetSize() == 0, p->GetSize() );

or

ASSERT( p->GetSize() == 0, "Actual size: " << p->GetSize() << " Actual size * 2: " << p->GetSize()*2 );

Please use CPPUNIT_ASSERT_EQUAL, which takes an actual and expected value. This pretty much eliminates the need for formatting a string, as the actual and expected values will be printed in the failure message.

You could also copy the implementation of this macro and the function it invokes and add additional macros for other types of comparisons. Another idea I tried out would be to use operator overloading to capture the value out of an expression. This (ab)uses operator overloading to capture the expression, but it seems perhaps a bit too hackish. I have included it to give you an idea of what is possible, but would not recommend its use:

#include <iostream>
#include <sstream>

class ExpressionPrinter
{
public:
  std::ostringstream result;

  template<typename T> ExpressionPrinter& operator<<(const T& other)
  {
    result << other;
    return *this;
  }

  template<typename T> ExpressionPrinter& operator<(const T& other)
  {
    result << " < ";
    result << other;
    return *this;
  }

  template<typename T> ExpressionPrinter& operator<=(const T& other)
  {
    result << " <= ";
    result << other;
    return *this;
  }

  template<typename T> ExpressionPrinter& operator>(const T& other)
  {
    result << " > ";
    result << other;
    return *this;
  }

  template<typename T> ExpressionPrinter& operator>=(const T& other)
  {
    result << " >= ";
    result << other;
    return *this;
  }

  template<typename T> ExpressionPrinter& operator==(const T& other)
  {
    result << " == ";
    result << other;
    return *this;
  }

  template<typename T> ExpressionPrinter& operator!=(const T& other)
  {
    result << " != ";
    result << other;
    return *this;
  }
};

#define ASSERT(X) doAssert((X), (ExpressionPrinter() << X));

void doAssert(bool result, const ExpressionPrinter& message)
{
  std::cout << "Result: " << result << ", Expression: " << message.result.str() << std::endl;
}

int main()
{
  int i = 1, j = 2;

  ASSERT(i < j);

  return 0;
}
#include <iostream>
...
ASSERT( p->GetSize() == 0, p->GetSize() );
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top