— Nov 22, 2013
Symmetry is beauty. This applies to lots of things, programming included.
Boolean methods answer a question with “yes” or “no”. To adequately test such a method, you must assert on the positive and negative cases. Chances are you’ll want the complementary method eventually, so let’s start with symmetry and see where it takes us.
Let’s say we have a
Person class as follows:
We’re presented with a feature that states a
Person should be able to report
if they are active. Let’s start with a spec:
And now for a very high-value implementation:
Yay! All green :). But, ahem, not exactly feature complete. Alright, so we
should probably test the negative case. At this point we’re presented with
a choice. Do we test the negative cases of
active? or introduce the
inactive?. We’ll choose symmetry:
Cool, these new specs are erroring with a
NoMethodError. We’ll implement
this complementary method as a function of
Nice, we see a properly failing spec. The final implementation is straight forward (althrough if we’re practicing TDD, we may get there in a couple steps):
Alright, so what have we accomplished? We have implemented a simple boolean method along with its complement, and we done this with tests providing adequate coverage for both methods. The complementary method could be argued YAGNI (“You ain’t gonna need it”), but in most cases you’ll end up negating your method. Having a complementary method feels symmetric… and beautiful. Further our specs cover the implementation well without duplication.
Symmetry not only looks good, it makes logical sense to client developers and makes your test suite more expressive. When you encounter a boolean method you probably assume its logical complement is defined. Perhaps in this case YAGNI may be set aside for expressiveness.
How do you feel about symmetry? How important is it to the interfaces you define?