Reputation: 136
When it comes to writing unit tests for functions or classes in C++, it seems popular writing them in separate source files from the original declarations and definitions (e.g. math_test.cpp for math.hpp/math.cpp). I wonder if writing them near the declarations might be better for the following reasons:
For example, I wonder I can put a unit test to a function declaration in a header file like this:
// plus.hpp
int plus(int a, int b);
UNITTEST{ assert(plus(1, 2) == 3); }
while the source file is as usual:
// plus.cpp
int plus(int a, int b) { return a + b; }
and only when I define a specific macro (e.g. ENABLE_UNITTEST) I expect the UNITTEST code to be evaluated by the compiler and executed by the test runner executable.
My questions are:
Upvotes: 2
Views: 2178
Reputation: 44268
Is there any existing C++ testing framework that supports writing tests like this? (I think it will cause a redefinition error when plus.hpp is included in multiple source files if the framework is not properly implemented)
You can implement such way with many exitsting frameworks (if not all of them), for example google test:
int plus(int a, int b);
#ifdef UNITTEST_ENABLED
TEST(Functions,plus)
{
EXPECT_EQ( 4, plus( 2, 2 ) );
}
#endif // UNITTEST_ENABLED
you just need to properly configure your build system to compile sources for tests with macro UNITTEST_ENABLED defined
Though I agree with @dasblinkenlight answer and believe this is not a good practice to mix test code with regular sources. For example when you cover your plus()
function in your code properly you should check positive with positive, positive with negative, negative with negative, and corner cases (max int + 0) etc. After you do that properly your actual function code will be well hidden inside tests so your source will become unreadable.
Even worse to put unit tests in header. Same reasons as above plus headers should only have declarations, not actual code.
Upvotes: 2
Reputation: 2740
I think what it comes down to is that it may seem perfectly reasonable for the example you gave. The projects that I work on however have several test files containing hundreds of lines. People are usually not just testing one single thing either but putting it through a plethora of test conditions.
Your way of doing things would get messy very quickly if your test cases every became longer then a line or two (or had multiple tests). Not to mention trying to find code and general readability would be greatly diminished.
Upvotes: 1
Reputation: 726987
Is it a good practice to write unit tests near the declarations like this?
No, it is not. It is not uncommon to have more unit test code than the actual code. Mixing up the two makes your system harder to maintain and refactor.
The idea to put unit tests along the main code looks appealing for small code examples like yours. In many instances, however, your unit test code would easily triple of even quadruple your actual code, especially if you aim for high code coverage. The simple size of the added code, along with its in-code documentation, will make it harder for people to change your system.
In addition, some unit tests need to maintain state during the run (setup and teardown functions of common testing framework deal with this). Mixing a placeholder for the state with the payload code would complicate matters even more.
Is there any existing C++ testing framework that supports writing tests like this?
Not that I know of.
If the answer for 2. is NO, is it possible to implement a testing framework like this?
It is certainly possible - for example, you can play all sorts of tricks with preprocessor macros and conditional compilation to extract unit tests from your "payload" code, and compile them separately. I do not think it is desirable, though.
Upvotes: 4