Ideally, I'd want the subclass to inherit all the superclass tests.
This is a source of confusion, in my mind at least, though dws touched on it earlier also.
There are two "chains of inheritance", for want of a better term, involved in this discussion. We have the superclass & subclass chain, and we have the superclass tests and the possiblity of the tests for the subclass 'inheriting' those within the superclass.
My view, based on my accumulated wisdom -- I use the term loosely -- from exposure to the various different methods I've used, is that using inheritance in the test chain, regardless of whether this is formal, language based inheritance, or cruder mechanisms by which the tests for the superclass would be run as a part of the testing cycle of the subclass, is bad practice.
My reasoning is, as I cited above
If the the superclass has many subclasses, re-running the superclass tests for every subclass achieves nothing.
The testing performed at each of the five levels I cited serve different purposes. Not only does mixing them cause duplication, it can also compromise the validity of the testing.
- Unit tests are best written internally to the code they test. Only by having sight of the implementation can one ensure that all the paths are covered.
- Functional verification specifically should not have sight of the code. It should be testing against the contract/specification, not the specific implementation.
I strongly disagree that specification testing is only a bean counting exercise. It is integral to the loose-coupling philosophy that allows independance between development teams working on seperate subsystems of an overall system. Ensuring and maintaining this loose coupling is the most important step in achieving cost effective and attributable development in large systems, which leads to the third reason.
Whilst tests are, of their very nature, inextricably tightly bound to the code they test, subclasses should be as loosely bound to their superclasses as possible.
The theoretical reasons for loose binding are very well documented, thought the practical manifestations of them are less well defined or recognised.
By creating an inheritance hierarchy in tests suites that mirrors the inheritance hierachy of the production code, you are creating an indirect tight binding between subclasses and their superclass.
If the need arises to swap out the current implementation of the superclass for an alternate, if good OO practice has been followed in the construction of the subclasses and they are loosly bound, then the replacement should require no changes in the subclasses.
However, if there is an indirect close-couplng between the subclasses test's and those of the superclass, then replacing the superclass will require replacing those tests, with the knock on effect of requiring changes to the tests in the otherwise unaffected subclasses.
Although the replacement superclass may perform the same function as that it replaced, it is quite likely that it will used a different implementation. It's unit test suite will therefore have to be different and anything inheriting from those tests will also be affected.
Whilst it would be theoretically possible to maintain loose-coupling in the test hierarchy, doing so would require significant design effort in the test suite. It's all code, and it's all possible, but the tests are there to support the main code. Once it becomes a project all of its own, it saps resources and you end up with the crazy possibility that a replacement superclass (production code) could be rejected on the that it's (test suite) (non-production) didn't fit with the "Test suite model".
That would really be a case of the tail wagging the dog.
And if anyone thinks that this level of stupidity couldn't happen, I have a couple of very long stories to show that it can and does. The biggest problem of software development in large organisations, is keeping the focus on the production code and away from ancillary areas.
Whilst testing, and source code maintenance and backups and documentation and media production and many other areas of the full picture are very important, they must support the development process, not drive or control it.
On the tyres thing: Most analogies don't stand up to deep scrutiny.
I'll hold my hand-up here and say that I got a long way into arguing with your crash-test scenario -- or rather the purpose of crash testing vehicles -- before throwing it away and "moving on" :)
abigail used it to make the point that sub-systems aren't islands and there is intereactions between them.
I used to make the point that he was correct, but that the different testing is required at different stages.
By their very nature, analogies tend to be over-simplified, but discussing the true nature of the system used in the anaology is fruitless. If the analogy helps in making the point being broached, it served it's purpose. If it didn't, move on.
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.