Let's assume I have a class called A with four members: a, b, c and d. During the testing, whenever I would want to check if the values of all the members are correct, I would have to make four assertions. It would be much simpler to create a method like this:
void compareA (const A& o, int a, int b, int c, int d)
{
CPPUNIT_ASSERT (o.a == a)
CPPUNIT_ASSERT (o.b == b)
/* ... */
}
and call it everytime I would like to check the members. But there is one problem with that: if an assertion fails, then I will get the line number inside the compareA() method, and not the line number the method was called at. In my own basic unit testing classes I have solved it by creating a macro CALL, used in the following way:
CALL (compareA (a, 0, 0, 0, 0))
The macro simply adds the method name and location to the current test path (and removes them after calling the method), and so, on failure I get the whole path leading to the assertion:
MyTest
compareA file.cpp 50
file.cpp 10
Of course, this could be used in a nested way (if compareA() would call another method this way), and the information about a failure could look like this:
Is there a way to do something like this in CPPUNIT? As I have seen so far, only the location of the assertion that failed is stored and I haven't found any macro or method for doing this in the documentation.
I know that for this example I could create a simple macro instead of the compareA method, but I would like to use this feature for much more complex auxiliary methods, and it would be much more convenient to use methods and not macros.
Regards,
Jakub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If you want to compare two of these things for equality, define an operator== that takes two of them, and have it return true or false, based on whether or not all of the elements match. Then, just use CPP_UNIT_ASSERT_EQUAL(a, b) and be done.
Oh, that means that you unit-test the development of this operator== to make sure that it works properly. ;) It also means that you'll probably need to write a bit of code to format the output of your object (e.g. operator<<(ostream&, your_object&) needs to be defined), but it'll be worth doing it after only two uses of it. ;)
In general, try to limit yourself to one assertion per test case. I can't effectively explain why here, but I've found it's really a good way to go, and someone smarter than me wrote a book and said so, too. ;)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yeah, I could do this :). I haven't thought about it when I was writing the example, and I admit it's pretty dumb :P.
However, I use these auxiliary methods in tests which cannot be changed that easily (or at least I think so ;)) and it would be really nice if there was a way to trace such calls. Is it possible?
Regards,
Jakub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not sure how to get the stacktrace, as it is called, to appear in the output for your test suite. However, if you run it in a debugger, such as gdb, you can easily display the complete history of method calls.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well, this would rather be an uncomfortable solution because I would have to debug every time a test using an auxiliary method failed. It would be much easier if it was handled by CppUnit and I could get the information about the auxiliary method calls in the output.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If you can't change the auxilliary functions, you're out of luck. If you can, just follow my earlier advice and keep the assertions in the test methods themselves. It will be so much cleaner, clearer, and simpler.
Ok, technically speaking you could inject some code into CppUnit as, say, "m_overloadFilename" and "m_overloadLineNumber," but then you'd have to put tons of calls to the thing that set those up throughout your testing code. I.e., you'd still have to edit the testing code itself. However, this again makes your tests more complicated and more fragile, and the point of unit testing is that the tests are dead-simple.
Things that can't easily be changed won't be until you make the effort to do so. However, there's no reason to remove "legacy" things that work. Just add the functionality I discussed and use it for new code. If the old tests ever require revisiting (even if only because they start failing), then those can be upgraded to suit.
Just remember: one assertion per test case makes your life a LOT easier.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think that at least for now the best solustion will be if I store the names and locations of the auxiliary method calls in a global array and create my own assertion macros that will convert the array to a string and then call the CPPUNIT_xxxx_MESSAGE macro with the string passed as the message. It won't be the best solution (it won't allow to go to the location of the auxiliary method call with a click for example) but it should be enough for now.
However, I have also posted a request for this feature to the Open Discussion forum. Maybe other CppUnit users will find it useful too.
Thank you for your help.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello
Let's assume I have a class called A with four members: a, b, c and d. During the testing, whenever I would want to check if the values of all the members are correct, I would have to make four assertions. It would be much simpler to create a method like this:
void compareA (const A& o, int a, int b, int c, int d)
{
CPPUNIT_ASSERT (o.a == a)
CPPUNIT_ASSERT (o.b == b)
/* ... */
}
and call it everytime I would like to check the members. But there is one problem with that: if an assertion fails, then I will get the line number inside the compareA() method, and not the line number the method was called at. In my own basic unit testing classes I have solved it by creating a macro CALL, used in the following way:
CALL (compareA (a, 0, 0, 0, 0))
The macro simply adds the method name and location to the current test path (and removes them after calling the method), and so, on failure I get the whole path leading to the assertion:
MyTest
compareA file.cpp 50
file.cpp 10
Of course, this could be used in a nested way (if compareA() would call another method this way), and the information about a failure could look like this:
MyTest
compareA file.cpp 50
anotherMethod file.cpp 52
file.cpp 10
Is there a way to do something like this in CPPUNIT? As I have seen so far, only the location of the assertion that failed is stored and I haven't found any macro or method for doing this in the documentation.
I know that for this example I could create a simple macro instead of the compareA method, but I would like to use this feature for much more complex auxiliary methods, and it would be much more convenient to use methods and not macros.
Regards,
Jakub
Don't do that. :)
If you want to compare two of these things for equality, define an operator== that takes two of them, and have it return true or false, based on whether or not all of the elements match. Then, just use CPP_UNIT_ASSERT_EQUAL(a, b) and be done.
Oh, that means that you unit-test the development of this operator== to make sure that it works properly. ;) It also means that you'll probably need to write a bit of code to format the output of your object (e.g. operator<<(ostream&, your_object&) needs to be defined), but it'll be worth doing it after only two uses of it. ;)
In general, try to limit yourself to one assertion per test case. I can't effectively explain why here, but I've found it's really a good way to go, and someone smarter than me wrote a book and said so, too. ;)
Yeah, I could do this :). I haven't thought about it when I was writing the example, and I admit it's pretty dumb :P.
However, I use these auxiliary methods in tests which cannot be changed that easily (or at least I think so ;)) and it would be really nice if there was a way to trace such calls. Is it possible?
Regards,
Jakub
I'm not sure how to get the stacktrace, as it is called, to appear in the output for your test suite. However, if you run it in a debugger, such as gdb, you can easily display the complete history of method calls.
Well, this would rather be an uncomfortable solution because I would have to debug every time a test using an auxiliary method failed. It would be much easier if it was handled by CppUnit and I could get the information about the auxiliary method calls in the output.
Granted, but it is the only suggestion I can think of as I am new to CppUnit myself. I apologize that I cannot provide any further help.
Layne
No problem. Thank you for your help anyway :).
If you can't change the auxilliary functions, you're out of luck. If you can, just follow my earlier advice and keep the assertions in the test methods themselves. It will be so much cleaner, clearer, and simpler.
Ok, technically speaking you could inject some code into CppUnit as, say, "m_overloadFilename" and "m_overloadLineNumber," but then you'd have to put tons of calls to the thing that set those up throughout your testing code. I.e., you'd still have to edit the testing code itself. However, this again makes your tests more complicated and more fragile, and the point of unit testing is that the tests are dead-simple.
Things that can't easily be changed won't be until you make the effort to do so. However, there's no reason to remove "legacy" things that work. Just add the functionality I discussed and use it for new code. If the old tests ever require revisiting (even if only because they start failing), then those can be upgraded to suit.
Just remember: one assertion per test case makes your life a LOT easier.
I think that at least for now the best solustion will be if I store the names and locations of the auxiliary method calls in a global array and create my own assertion macros that will convert the array to a string and then call the CPPUNIT_xxxx_MESSAGE macro with the string passed as the message. It won't be the best solution (it won't allow to go to the location of the auxiliary method call with a click for example) but it should be enough for now.
However, I have also posted a request for this feature to the Open Discussion forum. Maybe other CppUnit users will find it useful too.
Thank you for your help.