Say we have this hyper simple class hierchy:
public class SomeMath
{
public int Add(int x, int y)
{
return x + y;
}
}
public class MoreMath : SomeMath
{
public int Subtract(int x, int y)
{
return x - y;
}
}
Should I write tests for the Add
method when I write tests for the MoreMath
class? Or should I only care about that method when I am testing the SomeMath
class? More generally: Should I test all methods of a class, or should I only test "new" methods?
I can kind of come up with some reasons for both sides. For example, when testing all methods you will end up testing the same thing more than once, which is not so good and can become tedious. But if you don't test all methods, a change in SomeMath
might break usages of MoreMath
? Which would kind of be a bad thing too. I suppose it probably depends a bit on the case too. Like if it extends a class I have control over or not. But anyways, I'm a total test newbie, so I am curious to know what people smarter than I think about this :-)
First of all, I think that there are at least two factors that may influence your decision to do one or the other:
In TDD scenarios, I would tend to write a single test case for MoreMath that verifies that it derives from SomeMath, and then consider all of the members inherited from SomeMath to be covered.
However, that implies that, from a design perspective, it is an important design aspect that MoreMath derives from SomeMath. This would definitely be the case if you use SomeMath in a polymorphic way. However, it wouldn't be the case if you simply use inheritetance for reuse (not recommended, though).
In the latter case (inheritance is used for reuse), there is no conceptual connection between the parent and child classes, and you may be tempted to break the inheritance in the future. In such cases, having a test that verifies that the parent is correct is a poor safeguard.
From a Quality Assurance (QA) standpoint, each and every member of each and every class should be tested rigorously. This means that you should repeat the test code for each child class even if the test code would be the same, because you need to verify that no virtual method was overridden in an unexpected way. However, to stay DRY you can write them as Parameterized Tests, or perhaps use a tool such as Pex.
Personally, I rarely get to the QA phase. Usually, the test suite created during TDD is an adequate safety net... but that all depends on the type of software you build.