This post originated from an RSS feed registered with Agile Buzz
by Kevin Rutherford.
Original Post: grouping tests by expected outcome
Feed Title: silk and spinach
Feed URL: http://silkandspinach.net/blog/index.xml
Feed Description: kevin rutherford on agile software development and life in macclesfield
Cory Foy reports on a discussion over on the TDD list that I had somehow missed. The discussion began with a look at long names for unit tests, and ended with a suggestion for grouping tests according to the expected behaviour. Cory presents this example:
public class RoomRemovedFromListWhen {
public void lastUserLeaves() {
//...
}
public void roomIsKilledByModerator() {
//...
}
public void lastUserSessionTimesOut() {
//...
}
}
My first reaction to this was very positive, and I immediately began writing this to pass the idea on to you. But then as I mulled it over, a doubt crept in. You see, the tests are now grouped according to their outcome, rather than according to the interface they're testing. And I believe that's bad, because those outcomes may change independently of each other. It may be today's policy that the room is deleted when the last user leaves, but that could change in the future. Which means this test class has several independent reasons to change, and the very grouping that seems so cute here could turn out to be a drag on the adaptability of the product. This isn't unit testing, it's policy testing.
This example violates a classic rule of good design: Keep things together that change together; and keep things apart when they change independently.
I wonder if this has arisen because of a confusion of terms: "behaviour" as in behaviour-driven development and "behaviour" as in outcome are different. The first is about interface design, and is a good reason to group tests. Whereas the second is about policy, and is a good reason to keep tests apart. I like the naming convention aspect of this approach, but I fear the increased cost of change may be too high a price to pay...