19 May 2017

Naming Tests

I'm sure you have heard the old joke about the 2 hardest things in Computer Science. 

0. Naming Things
1. Cache Invalidation
2. Off by One Errors

That said, Naming Things is really hard. Sometimes it feels impossible to find a single word or short phrase that expresses what we intend. That said, putting the effort forth to name things well is very important to the readability of your code. This is even more important in your test suite. 

Lately we've been using Python and the unittest module therein. Therefore all my test methods start with the word test_. But, how do  we name things beyond that? Here is how I start.

First, name the class well. There are two choices here, first, to name the class after the test subject, VolumeCalculator and VolumeCalculatorTest. This is pretty standard practice and it is helpful for finding a tests. For example, if I'm looking at VolumeCalculator.calculate_volume(container) and I want to find it's tests, I can look for VolumeCalculatorTest.py and they are probably in there. Alternately, I could name my tests after the behavior that I'm after, for example CargoCapacityTest.py. I can use both of these techniques simultaneously as well, if for example, CargoCapacity uses VolumeCalculator and WeightLimitLookup, however, that might suggest some loose encapsulation of the overall Cargo Capacity activity (possibly those two are used in higher level method?). The key to any of this though is to be expressive and consistent without being too verbose.

Second, test method names. We've established that in unittest we'll start with test_ because we have to. But what comes after that? I suggest that you create a pattern and stick to it. One pattern might be test_{method}_{behavior}_{ext}. Where {ext} might be things like _fails, _succeeds, _yeilds_{value}. Again, the game here is to express the intent of the test. Some things you will observe are, if the test name is ridiculously long, the behavior might be too complicated, and if you can't figure out what the test should be named, you might not know what your testing -- you need to ask more questions to get this right. 

Third is organization. This isn't so much about naming as it is about namespaces. A lot of test suites can be very flat. However, if we organize our tests in namespaces like we organize our production code we can imply a scope for our tests that makes organizing them more logical to the reader. It makes the tests easy to find, and suggests to the reader something about the independent nature of these components in the suite. 

Of course all these suggestions are for tools like unittest, they would be different using a tool such as Cucumber, Behave, Jasmine, or RSpec. More on that later.