Sharing tests between derived classes

526 views
Skip to first unread message

Ryan Hartlage

unread,
Jul 1, 2013, 10:23:10 AM7/1/13
to cppu...@googlegroups.com
I'm writing a bunch of C "classes" that are 90% the same.  This 90% is shared by the classes by inheriting from a common (abstract) base class, but right now I have a lot of duplicate code in the test suites for each of the derived classes.  In the interest of not repeating myself I'd like to either share the tests somehow or find a way to obviate the need for testing of the common functionality in each concrete class.  Has anyone solved this problem yet?

Terry Yin

unread,
Jul 1, 2013, 7:26:10 PM7/1/13
to cppu...@googlegroups.com
Hi Ryan,

IMHO, instead of spend your time on unit test, you should spend time on your production code. Use inheritance to reuse implementation is quite obsoleted OO technique (use aggregation instead).

Then you can test the 'base' class separately and test the other classes with a mock object (or just use the 'base' class without caring its behavior).

br, Terry

On 2013-7-1, at 下午10:23, Ryan Hartlage <ryanpl...@gmail.com> wrote:

I'm writing a bunch of C "classes" that are 90% the same.  This 90% is shared by the classes by inheriting from a common (abstract) base class, but right now I have a lot of duplicate code in the test suites for each of the derived classes.  In the interest of not repeating myself I'd like to either share the tests somehow or find a way to obviate the need for testing of the common functionality in each concrete class.  Has anyone solved this problem yet?

--
You received this message because you are subscribed to the Google Groups "cpputest" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cpputest+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ryan Hartlage

unread,
Jul 1, 2013, 8:59:29 PM7/1/13
to cppu...@googlegroups.com
Hi Terry,

I absolutely agree with you about spending my time writing production code instead of wasting time on unnecessary unit tests.  I also agree with you regarding aggregation/composition -- this actually started as aggregation, but most of the calls were wrapper calls that were generating (nearly) pointless unit tests.  This led me to my current solution.

I follow your suggestion about mocking the base in principle, but I fail to see how it would work in practice.  Running a set of shared tests seems much more elegant (particularly because it doesn't specify implementation details!), but I haven't worked out a clean way to actually accomplish this.

Another place this would be useful is for different implementations of an interface (think multiple implementations of a map or another data structure, each optimized for a different workload or resource trade-off).  Each implementation would have the same externally visible behavior, but differ in their implementation details.  A set of tests delivered with the interface and easily linked to an implementation would very clearly document the interface, validate implementations, and even invalidate(!) implementations when/if the spec changes.

Ultimately, sharing tests seems like a natural fit for testing OO code, but is there a clean way to accomplish this with CppUTest?

Terry Yin

unread,
Jul 1, 2013, 9:38:34 PM7/1/13
to cppu...@googlegroups.com
Hi Ryan,

I think what you are looking for is "parameterized test", which in this case the parameter is the type information. CppUTest doesn't have that.

Can you show us your code?

br, Terry

Bas Vodde

unread,
Jul 2, 2013, 4:51:26 AM7/2/13
to cppu...@googlegroups.com

Hi Ryan,

In additional to what Terry says, usually the way I work is to extract test-fixtures in a seperate class and see where it goes from there. In the CppUTest code-base, you can find the "TestTestingFixture" which is an odd class name, but we use it quite a lot for extracting shared code cross many tests.

Alternatively, you can also have a common base-class, but I would recommend that.

In the JUnitOutputTests, I had refactored the common code so that it was very generic (kinda like parameterized tests generic) and after years I concluded it had made the code completely unreadable and unchangeable, so I'm rewriting that now :(

Thus, I'd focus on just extracting as much common code as possible (which would be a lot) and then writing short tests which would be very similar for different subclasses.

Hope this helps?

Thanks,

Bas

Ryan Hartlage

unread,
Jul 2, 2013, 9:30:10 AM7/2/13
to cppu...@googlegroups.com
Unfortunately I'm not allowed to show you the actual code.  I will look into parameterized unit tests, though.  Thanks for the tip!

Ryan

Ryan Hartlage

unread,
Jul 2, 2013, 10:21:26 AM7/2/13
to cppu...@googlegroups.com
Thanks Bas, I will look into TestTestingFixture and dig through your history for JUnitOutputTests.  I think you may be right that it's better to just deal with some repetition where necessary, but it would be nice to have a tool available.

Thanks again Bas and Terry

A. Robert S.

unread,
Sep 10, 2013, 5:04:57 PM9/10/13
to cppu...@googlegroups.com
Hi Ryan,

I found myself in a position where I had to run a  bunch of tests that basically differed in only two things:

1. They needed to instanciate a different class
2. They needed to use a different vector of strings to complare against.

I found that plain, old-fashioned macros worked great for me. Something like:

TEST(something) {
   GENERATE_TEXT_TO_TEST(MyClass);
   FAIL_UNLESS_ALL_LINES_EQUAL(my_vector_of_strings);
}

I have adopted this approach to a variety of similar situations. It takes code duplication out of my test cases like no other approach could.

Maybe you'll find this approach worth thinking about.

Regards,
Robert
Reply all
Reply to author
Forward
0 new messages