Does the user story script have evil?

So, I know that when it comes to user story scenarios, is specific , this is a good thing . However, I often go to the point where I ask myself: how specific should my scenario be?

For example, for user history:

So that project participants can collaborate on the project as a project manager, I want to be able to register new projects

We can have the following scenario:

Given that the project has never been registered in the system when the project manager registers this project, the registered project should appear in the indicated list of projects

Or we can be more specific with something like:

Given that Scott is a project manager, and the stackoverflow integration project has never been registered in the system, when Scott registers a stackoverflow integration project that identifies Jane as a project member, then the stackoverflow integration project should appear in the list of Jane projects

I found a second “more specific” one that will be useful when writing BDD specifications. Somewhere like scottTheProjectManager instead of projectManagerStub:

  • more attached to the real world (we don’t have stubs working as project managers .. or we?)
  • it’s easier to refer whenever necessary in the context of the specification (otherwise I will say “project manager” or “project manager who registered the project” ... etc.

Am I right in my conclusion? Will this specificity hurt me when a change in history happens?

Thank you so much!

<h / "> Update

The above question concerns not only the names of people instead of the names of roles, but also the replacement of all placeholders in your script with the names of real instances. And in real cases, I don’t mean that in fact we have someone named Scott working as a project manager, he just gives names to abstract placeholders in order to realize the above advantages.

I will try to show how these benefits are realized by including the following code, which is a complete BDD style specification using the StoryQ structure

[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 = "Qaru 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)); } } 
+7
source share
5 answers

The first "scenario" that you give is actually an acceptance criterion. It defines a rule that should work for all types of project managers, members and specified projects.

The second scenario is an example of acceptance criteria in action using realistic data. A critical aspect of BDD is the use of such examples in a conversation so that any other aspects of eligibility criteria for the story can be discussed.

For example, if a stackoverflow integration project is already registered, what happens when Scott tries to register it again? Is there any scenario in which Jane’s appointment to the project could be rejected? Is Jane's project assignment the only valuable outcome? Does she receive an email?

You can probably already see how much easier it is to use specific data when discussing the scenario. Remember also that:

  • with chains more important
  • capturing conversations more important than
  • chain automation .

If you do all three at the same time, then, but uncomfortable, but not a compromise in conversations for the sake of automation.

+3
source

Custom Characters is a very powerful, but difficult to understand concept. That's right, they can guide you to a simplified, optimized user experience. Done wrong, they take time and give people in the team a subjective reason to shout at each other.

This will open http://www.agile-ux.com/2009/12/02/personas-in-agile-development-yes-we-can/ for the starting point. There is a lot of literature on this subject, although it does not mainly apply to BDD.

The most important piece of advice I can give is that when defining your characters it is important to be very specific as to what charms / motivates / upsets them, but this specificity should be from the point of view of the world as a whole or calculations in general - do not associate these things with specific aspects of your product or personal aspirations for the product, because otherwise 1) the person will quickly become obsolete and needs to be recreated, and 2) the person will ultimately be used as a subjective weapon to further your personal aspirations I, not as a fact-based tool to improve, making the best product for real people. This is much easier said than done.

+2
source

It is good to use names for roles, as they facilitate understanding of the story; they attract more to your primates brain because he loves people and hates abstraction. However, you must take care! Try to make sure that the names you use do not match the name of someone you really work with - it would be terribly confusing - and not encode biases - the project is not biased because it cannot have opinions. Also, do not use the same name for different roles; while reality can be a messy mix with people with many roles, user stories should not be mixed in this way because it is just confusing.

+1
source

Compare the following in your example:

Given that Scott is a project manager, and the stackoverflow integration project has never been registered with the system. When Scott registers a stackoverflow integration project that indicates Jane as a member of the project, then the stackoverflow integration project should appear in the list of Jane projects

VS:

For the project manager and an unregistered project, when the Project Manager registers the project and indicates a team member, then the project should appear in the list of projects of the project participants.

Note that the wording of the second example above is not too different from the first example that you indicated in your question, but it is slightly different, so it reads as if it is a little more complete. I think that this is something that you might feel is missing, and if so, I would consider it as a kind of “smell of history,” and if so, I will continue to ask questions and rewrite until while the story / script feels more complete.

Personally, I think that using persona distracts me from the task, and I don’t like it when my test code ends up littered with text that cannot be read as if it refers to what I'm testing. If, on the other hand, you use a data-based approach, and for this purpose you are defining some kind of data structure, then it makes sense to populate this structure with names that may make sense within the area in which they are tested.

I think one of the risks with using a person is that they can sometimes be a substitute for the lazy method name or even worse, because for bored programmers you can try to introduce a little humor into your code. Not that I thought it was bad to have a little fun with your names, but if they don't give value to stake holders, then they shouldn't be used.

Another thought arises with me, although you can have the best of both worlds. If you indicate your user identity as the data for the plot scenario, then it will be useful for you to keep your code clean and to such an extent, but you can make the conclusion more specific in terms of the actual test execution. For example:

 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(AProjectManager, "Scott") .And(AnUnRegisteredProject, "Qaru Integration") .When(TheProjectManagerRegistersTheProject) .And(TheProjectManagerSpecifiesATeamMember, "Jane") .Then(ThenTheProjectShouldAppearInTheTeamMembersListOfProjects) .Execute(); 
+1
source

While your aproach having a named specific user compartment is much easier to understand for a domain expert (since the domain expert knows * Scott_the_project_manager * and its tasks), but I think this aproach violates Single_responsibility_principle : one person can have multiple roles.

Scott may also be involved in marketing, and * Magret_the_project_manager * may have different responsibilities than Scott

0
source

All Articles