So I know that when it comes to user stories scenarios, being specific is a good thing. However, I frequently come to a point where I ask myself: How specific should my scenario be?
For instance, for the user story:
In order to allow project members to collaborate over a project, as a project manager, I want to be able to register new projects
We can have the following scenario:
Given a project has never been registered in the system, when a project manager registers that project, the registered project should appear in the specified member's list of projects
Or we can be more specific with something like:
Given Scott is a project manager and stackoverflow integration project has never been registered in the system, when Scott registers stackoverflow integration project specifying Jane as a project member, then stackoverflow integration project should appear in Jane's list of projects
I've found the 2nd "more specific" one to be handy when writing BDD specifications. Where having something like scottTheProjectManager instead of projectManagerStub is:
- more aligned to the real world (we don't have stubs working as project managers.. or do we?)
- easier to refer to whenever needed in that specification context (otherwise, I will keep saying "that project manager" or "the project manager who registered the project"... etc.
Am I right in my conclusion? Will that specificity harm me when a change occur on a story?
Thanks a lot!
Update
The question above is not only about having person names instead of roles names, it's about replacing all placeholders in your scenario with names of real instances. And by real instances I don't mean that we actually have someone called Scott working as a project manager, it's just giving names to abstract placeholders in order to realize the aforementioned benefits.
I will try to show how these benefits are realized by including the following code which represents a full BDD style specification using StoryQ framework
[TestFixture]
public class ProjectRegistrationSpecs
{
[Test]
public void ProjectRegistration()
{
new Story("Project Registration")
.InOrderTo("allow project members to collaborate over a project")
.AsA("project manager")
.IWant("to be able to register new projects")
.WithScenario("New Project Registration")
.Given(ScottIsAProjectManager)
.And(StackoverflowIntegrationProjectHasNeverBeenRegistered)
.When(ScottRegistersStackoverflowIntegrationProjectSpecifyingJaneAsAnAnalyst)
.Then(StackoverflowIntegrationProjectShouldAppearInJanesListOfProjects)
.Execute();
}
//Since Scott and Jane are just instances that have meaning in the context of this user story only, they're defined private
private ProjectManager scottTheProjectManager;
private Project stackOverFlowIntegrationProject;
private Employee janeTheAnalyst;
//Initialize the stubs in the constructor
public ProjectRegistrationSpecs()
{
scottTheProjectManager = new ProjectManager()
{
Id = new Guid("{A1596CFC-5FA5-4f67-AC7E-5B140F312D52}")
};
stackOverFlowIntegrationProject = new Project()
{
Id = new Guid("{F4CD5DDE-861E-4e18-8021-730B7F47C232}"),
Name = "Stack Overflow Integration"
};
}
private void ScottIsAProjectManager()
{
container.Get<IDataProvider>().Repository<ProjectManager>().Add(scottTheProjectManager);
}
private void StackoverflowIntegrationProjectHasNeverBeenRegisteredInTheSystem()
{
var provider = container.Get<IDataProvider>();
var project = provider.Repository<Project>().SingleOrDefault(p => p.Name == stackOverFlowIntegrationProject.Name);
if (null != project)
provider.Repository<Project>().Delete(project);
}
private void ScottRegistersStackoverflowIntegrationProjectSpecifyingJaneAsAProjectMember()
{
stackOverFlowIntegrationProject.Members.Add(janeTheAnalyst);
scottTheProjectManager.RegisterProject(stackOverFlowIntegrationProject);
}
//instead of saying something like TheProjectThatWasAddedByTheProjectManagerShouldAppearInTheProjectMembersList, we have:
private void StackoverflowIntegrationProjectShouldAppearInJanesListOfProjects()
{
Assert.That(janeTheAnalyst.Projects.Any(p => p.Id == stackOverFlowIntegrationProject.Id));
}
}