Templated test code?
March 19, 2008 [C++, Lean and Agile, Tech, Test Driven]At work at the moment, as part of an initiative to get with the 21st century, we are waking up to testing our code.
Thus, I am writing a lot of unit tests for old code, which can be soul-destroyingly repetitive and very pointless-feeling (even though really I do see a great value in the end result - tested code is refactorable code).
Often, tests have a lot in common with each other, so it feels right to reduce code repetition, and factor things into functions etc. The Right Way of doing this is to leave your tests as straightforward as possible, with preferably no code branches at all, just declarative statements.
Contemplating writing unit tests for the same method on 20+ very similar classes, using a template function "feels" right, for normal code values of "feel". However, for test code, maybe it's wrong?
My question is: is it ok to write a test function like this?:
void test_all_thingies() { test_One_Thingy<Thingy1>(); test_One_Thingy<Thingy2>(); test_One_Thingy<Thingy3>(); test_One_Thingy<Thingy4>(); } template< class T > void test_One_Thingy() { T thingy; thingy.doSomething(); TEST_ASSERT( thingy.isSomething() ); }
Worse still, is this ok?
void test_all_thingies() { test_One_Thingy<Thingy1>( "Thingy1 expected output" ); test_One_Thingy<Thingy2>( "Thingy2 expected output" ); test_One_Thingy<Thingy3>( "Thingy3 expected output" ); test_One_Thingy<Thingy4>( "Thingy4 expected output" ); } template< class T > void test_One_Thingy( std::string expected_output ) { T thingy; thingy.doSomething(); TEST_ASSERT( thingy.getOutput() == expected_output ); }
Reasons for: otherwise I'm going to be writing huge amounts of copy-pasted code (unless someone can suggest a better way?).
Reasons against: how clear is it going to be which class failed the test when it fails?
Update: fixed unescaped diagonal brackets.