Test Case Inheritance Mirroring Objects to Test

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

Post Reply
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Test Case Inheritance Mirroring Objects to Test

Post by Ollie Saunders »

Is it a good idea?

Code: Select all

class Foo { /* loads of stuff */ } 
class Bar extends Foo { /* extra stuff */ }

class TestOfFoo extends UnitTestCase { /* tests for Foo */ }
class TestOfBar extends TestOFFoo { /* override bits and pieces of the previous test case */ }
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Pretty redundant, wouldn't you say?
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

I'm not sure. I suppose it would be nice to ensure that extensions to Foo in Bar don't break old Foo functionality still present in Bar. But it makes tests dependent and they are supposed to be isolated.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

That just seems silly. That's what group tests are for. It is common practise to inherit from a base test case which provides some setUp() and tearDown() methods as well as factories and stuff but to extend on "full working" test case with another seems a bit redundant and sounds like you want a group test.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

Well, sometimes the redundancy can be good. Here's when I would do something like that:

1. When Bar overloads existing Foo methods, but they have an intersection of functionality. Bar may go about calculating the fifth term of the Fibonacci series differently from its parent Foo in order to add some extra functionality, so obviously the tests would be applicable to both Foo and Bar, and should be done on both.

Real world example: the HTML spec defines a series of data types called Pixels, Length and Multilength. Each of these allows a superset of one another: Pixels accepts only whole numbers, Length accepts Pixel's input as percentages. Multilength accepts the prior two, as well as stretchy space (indicated with an asterisk). For the unit tests, anything PixelsTest performs on Pixels, has to also be checked on Length and Multilength, to make sure the classes are deferring properly.

2. A more generalized case is if there are many Bars (which there should be, considering the meaning of inheritance), which share a similar interface. Then, you might want to inherit out of not a test-case but a harness, with a bunch of handy assertions for that specific class of objects. I do that all the time, saves for a lot of typing.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Then, you might want to inherit out of not a test-case but a harness, with a bunch of handy assertions for that specific class of objects. I do that all the time, saves for a lot of typing.
Yes I looked up the page on "Reusing tests" on lastcraft and found that was recommended there too. I haven't done that in the past but I will be in future.

However that isn't the same as what I'm asking here.

In general, and this is something I definitely wish to remedy, I don't put as much effort into tests. If they work they work that's it. But this seems to bite me in the arse all the time so this is why I'm asking this.
Post Reply