grouping tests by expected outcome

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…

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s