是否有特定的用户故事场景邪恶?

所以我知道,当谈到用户故事场景时,具体是一件好事。但是,我经常谈到自己的问题:我的情景有多具体? 例如,对于用户故事:   为了允许项目成员在项目上进行协作,作为项目经理,我希望能够注册新项目 我们可以有以下场景:   鉴于项目从未在系统中注册过,当项目经理注册该项目时,注册的项目应出现在指定成员的项目列表中 或者我们可以更具体地说:   鉴于Scott是项目经理和stackoverflow集成项目从未在系统中注册,当Scott注册指定Jane作为项目成员的stackoverflow集成项目时,stackoverflow集成项目应该出现在Jane的项目列表中 在编写BDD规范时,我发现了第二个“更具体”的方法。有像scottTheProjectManager而不是projectManagerStub的东西是: 更符合现实世界(我们没有存根作为项目经理......或者我们呢?) 在规范上下文中需要时更容易引用(否则,我将继续说“项目经理”或“注册项目的项目经理”......等。 我的结论是对的吗?当故事发生变化时,这种特殊性是否会伤害我? 非常感谢! 更新 上面的问题不仅仅是关于拥有人名而不是角色名,而是关于用实例的名称替换场景中的所有占位符。实际上,我并不是说我们实际上有一个名叫斯科特的人担任项目经理,它只是给抽象占位符命名以实现上述好处。 我将尝试通过包含以下代码来展示如何实现这些好处,该代码使用StoryQ框架表示完整的BDD样式规范
[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));
    }
}
    
已邀请:
您提供的第一个“方案”实际上是验收标准。它指定了一个适用于所有类型的项目经理,成员和指定项目的规则。 第二种情况是使用实际数据的行动中的验收标准的示例。 BDD最重要的方面是在对话中使用这样的例子,以便讨论故事接受标准的任何其他方面。 例如,鉴于stackoverflow集成项目已经注册,当Scott尝试再次注册时会发生什么?是否有任何情况可以拒绝Jane对项目的分配? Jane对该项目的任务是唯一有价值的结果吗?她收到有关它的电子邮件吗? 您可能已经看到在讨论场景时使用特定数据更容易。还要记住: 进行对话比重要 捕捉比这更重要的对话 自动化对话。 如果你在同一时间完成所有这三项工作,那就值得称赞,但为了实现自动化,不要在谈话中妥协。     
“用户角色”是一个非常强大但难以掌握的概念。如果做得好,他们可以引导您实现简化的优化用户体验。做错了,他们花时间给团队成员一个主观的理由互相吼叫。 查看http://www.agile-ux.com/2009/12/02/personas-in-agile-development-yes-we-can/作为起点。关于这一主题的文献很多,但主要不是BDD特有的。 我能给出的最重要的建议是,在定义你的人物角色时,重要的是要非常具体地说明喜欢/激励/挫败他们的东西,但这种特殊性应该是整个世界或一般的计算 - 不要将这些东西与产品的特定方面或产品的个人愿望联系起来,因为否则1)人格将很快变得过时并需要重新创建; 2)这些人最终会被用作推动个人发展的主观武器愿望,而不是作为一个事实为基础的工具,以改善为真人创造最好的产品。这说起来容易做起来难。     
最好在那里使用角色名称,因为它们可以更容易理解故事;他们更喜欢你的灵长类大脑,因为它喜欢个人,讨厌抽象。但是,你必须小心!尽量确保你使用的名字与你实际工作的任何人的名字都不匹配 - 这是非常令人困惑的 - 并且不会对偏见进行编码 - 项目不是偏见的事情,因为它不能有意见。也不要对不同的角色使用相同的名称;虽然现实可能是一个混乱的组合,人们有很多角色,用户故事不应该这样混淆,因为它只是简单的混乱。     
比较您的示例中的以下内容:   鉴于Scott是一个项目经理,而stackoverflow集成项目从未在系统中注册,当Scott注册指定Jane作为项目成员的stackoverflow集成项目时,stackoverflow集成项目应出现在Jane的项目列表中 VS:   给定项目经理和未注册的项目,当项目经理注册项目并指定团队成员时,项目应出现在团队成员的项目列表中。 请注意,上面第二个示例的措辞与您在问题中给出的第一个示例没有太大差别,但它略有不同,因此它读起来好像它更完整一些。我认为这是你可能觉得缺少的一种方式,如果是这种情况,我会把它视为一种“故事气味”,如果是这样的话,我会不断提问和重写直到故事情节感觉更完整。 就个人而言,我发现角色的使用让我分心于手头的任务,我不喜欢最终得到的测试代码充斥着看起来不像是我所测试的东西的文本。另一方面,如果您采用数据驱动的方法并且为此目的定义某种数据结构,那么在该结构中填充名称可以在其测试范围内有意义的情况下是有意义的。 我认为使用角色的风险之一是它们有时最终可以替代懒惰的方法命名,甚至更糟糕的是作为无聊的程序员尝试在代码中注入一点点幽默的手段。并不是说我对你的名字有一点乐趣是不好的,但是如果他们没有为利益相关者提供价值,那么就不应该使用它们。 我想到了另一个想法,那就是你可以拥有两全其美。如果您将用户角色指定为要提供给故事场景的数据,那么您可以保持代码清洁,但是您可以使输出在实际测试执行方面看起来更具体一些。例如:
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, "Stack Overflow Integration")
                .When(TheProjectManagerRegistersTheProject)
                    .And(TheProjectManagerSpecifiesATeamMember, "Jane")
                .Then(ThenTheProjectShouldAppearInTheTeamMembersListOfProjects)
    .Execute();
    
虽然您的aproach具有指定的特定用户托架对于域专家来说更容易理解(因为 领域专家知道* Scott_the_project_manager *和他的任务)但我认为这种方法违反了Single_responsibility_principle:一个人可以拥有多个角色。 斯科特也可能参与市场营销,* Magret_the_project_manager *可能与Scott有不同的责任     

要回复问题请先登录注册