Tuesday 14 October 2008

Non Descriptive Scenario Method Name

This is the first entry in a series of posts that provide practical advice on how to avoid or refactor away from common functional testing smells.

Non descriptive scenario method names can easily be identified by the presence of extremely short method names that provide little or no insight into the scenario being executed. For example:


public class SignInAcceptanceScenarios {

@Test
public void signIn() {
...
}
}

So, what sign in scenario is being executed here? Known user? Unknown user? The only way to find out is to read what the method is doing. Variations on this theme include partial attempts to describe the scenario. For example:


public class SignInAcceptanceScenarios {

@Test
public void signInHappyScenario() {
...
}

@Test
public void signInSadScenario() {
...
}
}

Using story and scenario identifiers in scenario method names should also be avoided. Who would like to hazard a guess as to what behaviour the following scenarios describe?


public class SignInAcceptanceScenarios {

@Test
public void story145Scenario1() {
...
}

@Test
public void story145Scenario2() {
...
}

@Test
public void story345Scenario1() {
...
}
}

The use of scenario revealing method names in each of the examples would be far more helpful.

Scenario Revealing Method Names

I tend to prefer descriptive method names that describe the scenario being executed. A downside of this style is that it can lead to some very long method names. However, I would rather read a longer method name than a shorter one that has some important part of the scenario missing. Alternatively, if method names get ridiculously long then they can often be rephrased in a more concise manner. Personally I don't worry too much about long method names. When writing scenarios I aim for an accurate and clear description of the scenario being executed.

Non descriptive scenario methods can easily be renamed, once the scenario has been understood, so that the scenario is clearly described using a scenario revealing method name. For example:


public class SignInAcceptanceScenarios {

@Test
public void shouldPresentKnownUserWithTheWelcomePage() {
...
}

@Test
public void shouldDeclineUnknownUserAndAskThemToTryAgain() {
...
}

@Test
public void shouldLockAccountAfterThreeSubsequentFailedSignInAttempt() {
...
}
}

A subtle alternative to prefixing scenario method names with 'should' is to simply provide a description of the expected behaviour. I shall leave it as an exercise for readers to decide which style they prefer. My only advice, as with most things when developing software, is to be consistent. For example:


public class SignInAcceptanceScenarios {

@Test
public void knownUserIsPresentedWithTheWelcomePage() {
...
}

@Test
public void unknownUserIsDeclinedAndAskedToTryAgain() {
...
}

@Test
public void userAccountIsLockedAfterThreeSubsequentFailedSignInAttempts() {
...
}
}

Scenario revealing methods are a huge improvement over their less descriptive counterparts, allowing readers to quickly grasp the intended behaviour
of a given functional area. The improved SignInAcceptanceScenarios class really does serve as documentation describing the behaviour of the sign in functionality provided by the application.

2 comments:

Alexandre Martinez said...

Another great feature provided by use of descriptive scenario methods is the ability to generate user stories summary for the current scenario. It provides easy and interesting documentation even for someone not interested in test coding details.

Andy said...

I've run into some resistance to long method names in scenarios. My response is that we are going to be reading the scenario names (when browsing through the code, in the outline view, or in the JUnit runner view) far more often than we spend typing the name in the first place, so it's worth taking the extra time and marginal typing effort.