I'd like to get some opinion about testing methodology.
Lets assume we have class A and B. Class B uses functionality of class A. The B class is fully tested and thus some test coverage is also applied indirectly for class A.
Should I write full tests directly for class A? Or should I test only not tested A class functionality?
I am asking because maybe in the future there will be possibility that the B class will be removed or modified in the way that it might not use the same functionality from A class so it might leave some methods untested. What would you do?
IMO, you should test B
's behavior without based on the fact that A
would already be tested.
Actually, there are three cases:
A
and B
BELONGING TO THE SAME LAYER:
If A
is created through refactor cycle (extract class) of B
(happens often while practicing a good TDD), then A
should TOTALLY be left untested! No need to test it at all!
Indeed, structure of code (in this case, separation of classes/SRP) should be independent of Unit concept; B
and A
in this case belonging to the same unit.
If A
existed BEFORE B
, B
should not be based on this fact, and B
's whole behavior should be tested.
A
and B
NOT BELONGING TO THE SAME LAYER (distinct boundaries for instance):
B
is a GUI class, and A
a business class, then A
should be doubled/mocked when testing B
, and also A
should have a full test dedicated for it.behavior/feature
notion.To understand why, read this recent article of Uncle Bob dealing with this concept:
http://blog.8thlight.com/uncle-bob/2014/01/27/TheChickenOrTheRoad.html?utm_source=hootsuite&utm_campaign=hootsuite
Excerpt of it:
It is a common misconception that the design of the tests must mirror the design of the production code. TDD does not require, as the Author suggests, "that every unit in your system is paired with a well-designed [...] unit test." Indeed, that's one of the reasons that many of us have stopped calling them "unit" tests.
Note: TDD doesn't care about "future", in the contrary, it helps you to write as much code as you need, no more. Therefore you should not worry about this:
in the future there will be possibility that the B class will be removed or modified
If you wrote good tests (I prefer the word "specs"), such removal would be detected immediately.
Yes, you should fully test A
.
B
might change at some point down the road, so just because it uses A
now doesn't mean that it always will.
B
may not use all of the functionality of A
which means that you're not testing all of your code.
Definately write full tests for class A. You kind of answered your own question here:
(...)maybe in the future there will be possibility that the B class will be removed or modified in the way that it might not use the same functionality from A class so it might leave some methods untested.
The general thought behind unittesting is that each unit is comprised of a Unit of Work. This can be as small as a method or as big as several methods working together.
You have already covered the scenario where B is dependent on A but from your story we can assume A will also be used separately. Therefore A should also be tested since it is a separate Unit of Work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With