Recently on the TDD list , we were discussing the benefits/drawbacks of long test names. I had posted an example to one I use in my Fitnesse talks that looks like public void RemovingLastUserFromRoomRemovesRoomFromAvailableRoomList() {}
. Jeff Langr initially suggested something more along the lines of EmptiedRoomIsUnavailable
, which I thought was a little too concise to be able to tell at a glance what was going on inside.
After some more discussion, it prompted a different way of thinking about grouping tests. Usually I group them based on the production class I’m testing, basically one test class to one production class. But what if instead of grouping by class, we grouped by behavior? Something like this might come about:
public class RoomRemovedFromListWhen {
public void lastUserLeaves() {
//...
}
public void roomIsKilledByModerator() {
//...
}
public void lastUserSessionTimesOut() {
//...
}
}
The above seems to really capture the behavior we are trying to test, and the conditions that behavior could occur in. It will be interesting to see how this affects my thinking about tests in our test suites.
This looks a lot like the direction the BDD folks are heading with RSpec.
Ed, that was my first reaction too. But I now suspect that’s a confusion of vocabulary. And I also feel the technique has a cost – see my blog for a full explanation.
Kevin,
I see you point about it testing the Policy rather than the interface.
For me, I think the underlying uneasiness maybe because the ClassUnderTest is still a single class.
However, if the Policy of removing room was in a separate class on its own, and delegated to from the original class, then i’d see it as being a normal test of interface.
Basically I see the TestClass name as hinting the original class may have too many responsibilities. It can be broken down an each class tested independently, if need be.
“I thought was a little too concise to be able to tell at a glance what was going on inside.”
I think that’s the point. Consider looking at *just* the test names as a whole. They should provide a concise summary of the class capabilities. As a developer I want to know, what does this class do, and what specifically do I need to understand? Well, perhaps I’m interested in knowing under what conditions empty rooms happen. I don’t want the details of each circumstance, just a summary of the cases.
A test name should not repeat its contents–the contents of the test are the “how.” The name of the test should be a summarization, not a blow-by-blow account of the implementation.