views:

92

answers:

2

I'm just starting to use CxxTest and would like to test whether a std::vector has been sorted correctly. Here's my test so far:

void testSort() {
  std::sort(vec.begin(), vec.end()); // This could be any sorting function

  for (unsigned int i = 0; i < vec.size() - 1; ++i) {
    TS_ASSERT(vec[i] <= vec[i + 1]);
  }
}

Obviously, CxxTest does not provide a TS_ASSERT_SORTED assertion, but is there a way to write custom assertions? That would allow me to do this:

void testSort() {
  std::sort(vec.begin(), vec.end()); // This could be any sorting function

  TS_ASSERT_SORTED(vec);
}

It's significantly easier to see the intent of the test when it's written this way.

I looked through the CxxTest user's guide but couldn't figure out whether you can write custom assertions like this. As an alternative, I could write a class IsSorted and implement its operator(). I could then write the test like this:

void testSort() {
  std::sort(vec.begin(), vec.end()); // This could be any sorting function

  TS_ASSERT_PREDICATE(IsSorted, vec);
}

I'm guessing this is the correct approach. If I do this, though, should I place the definition of class IsSorted in its own header file, separate from my test suite? I'm still trying to figure out the best practices associated with unit testing, especially in this framework.

One final question: should I be sorting the vector in the setUp() method or in the test itself?

A: 

You could use a #define


#define TS_ASSERT_PREDICATE( vec )\
    std::vector tmp = vec;\
    for(int i = 0; i  tmp[i+1]) \
            return false;\ 
    }\ 
    return true;\ 
}
martiert
The `TS_ASSERT` macros must do more than return a bool...otherwise, how would the variable values be output when a test failed?
ThisSuitIsBlackNot
A: 

Well, the assertions are just preprocessor macros, so you could probably implement them however you want, and then #define a macro for them. I'd think it'd be better to use a name that doesn't start with TS_ASSERT_, so that you don't confuse later readers of the code.

The predicate version doesn't look all that clumsy to me - I'd probably go with that, or possibly implement a check_ method on the class you're testing, and call that from the test. I often end up needing methods that validate the internal structure of the class for run-time debugging & logging, anyway...

Mark Bessey