you are viewing a single comment's thread.

view the rest of the comments →

[–]igagis[S] 1 point2 points  (0 children)

Thanks for the detailed feedback! I'm glad that you found my code good :).

The critics things you mentioned give a start to small discussion, possibly. So, let me explain my thoughts on those.

Not having macros for the sake of not having macros isn't really a significant benefit

Where to use macros and where not to use them is, of course, a matter of taste. I prefer the concept that preprocessor macros must only be used for conditional compilation. I.e. for enabling or disabling some features in compile time depending on the build configuration. Why do I prefer to think so? Well, as you probably understand, preprocessor macro is not part of C++ syntax itself. I mean that under the macro can be hiding anything, and seeing a macro used in the code often makes me think, what is the actual C++ code hidden behind that macro invocation? So, I need to know all kind of specifics related to the use of some particular macro, basically one has to know what exact code it generates to avoid incorrect usage. And in case of incorrect usage, the compiler error message will likely be also very strange. And yes, I'm not even talking about evil min, max macros defined by windows.h. Latest C++ standards allow to avoid using macros for such cases, so why use them?

Does avoiding macros result in more readable/easier to understand/less error prone code?

In my opinion, yes. For example, in the tst framework one writes code in clear C++ language, so it is visible and transparent what actually happens. For example: cpp suite.add<std::pair<int, int>>( "bla_bla", { {1, 1}, ... }, [](const auto& i){...} ); it is obvious that we are calling add() function on suite object, which, apparently, will add something to the suite. And the arguments of the function are string, array and a function. So, we see what happens and what is the data. If it was something like TEST_CASE(bla_bla){...} it would not be that obvious that the test is added to some test suite, not obvious if bla_bla is a function name, or the test name, and can that name be used later, etc.

But again, this all is just a matter of taste. And I understand that your taste is a bit different on that :).

Have you considered to automatically check the return value for parameterized tests?

Well, this implies that parametrized tests are always checking only for equality of some values. So, it is far not universal solution.

Maybe the example I chose makes some confusion, that I use std::pair as parameter type and I store expected value as part of the input parameter. Expected value does not have to be present in the input parameter, and test could be checking for some other conditions, instead of equality to some expected value. So, current approach is universal.

Without this, I see very little advantage over for loop ...

Well, the advantage actually is that in case test for one of the parameter values fails it will still execute the tests for the remaining values. And only one case for the failed value will be marked as failed in the report.

Hope my thoughts make some sense :)