【问题标题】:Is having specific user story scenarios evil?拥有特定的用户故事场景是邪恶的吗?
【发布时间】:2011-04-03 03:37:05
【问题描述】:

所以我知道,当涉及到用户故事场景时,being specificgood thing。但是,我经常会问自己:我的场景应该有多具体?

例如,对于用户故事:

为了让项目成员就项目进行协作,作为项目经理,我希望能够注册新项目

我们可以有以下场景:

给定一个项目从未在系统中注册过,当项目经理注册该项目时,注册的项目应该出现在指定成员的项目列表中

或者我们可以更具体的说:

鉴于 Scott 是项目经理,而 stackoverflow 集成项目 从未在系统中注册,此时 Scott 注册 stackoverflow 集成project 指定 Jane 作为项目成员,那么 stackoverflow 集成项目 应该出现在 Jane 的项目列表中

我发现第二个“更具体”的规范在编写 BDD 规范时非常方便。有 scottTheProjectManager 而不是 projectManagerStub 之类的地方是:

  • 更符合现实世界(我们没有存根担任项目经理……或者我们有吗?)
  • 在需要时更容易在该规范上下文中引用(否则,我会一直说“那个项目经理”或“注册项目的项目经理”......等等。

我的结论对吗?当故事发生变化时,这种特殊性会伤害我吗?

非常感谢!


更新

上面的问题不仅是关于使用 person names 而不是 roles names,而是关于将场景中的所有 placeholders 替换为真实的事例。通过真实的例子,我并不是说我们实际上有一个叫 Scott 的人担任项目经理,它只是给抽象占位符命名以实现上述好处。

我将尝试通过包含以下代码来展示这些好处是如何实现的,该代码表示​​使用 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));
    }
}

【问题讨论】:

    标签: c# bdd user-stories storyq


    【解决方案1】:

    您给出的第一个“场景”实际上是验收标准。它指定了适用于所有类型的项目经理、成员和指定项目的规则。

    第二个场景是使用真实数据的验收标准示例。 BDD 最重要的方面是在对话中使用此类示例,以便可以讨论故事接受标准的任何其他方面。

    例如,鉴于 stackoverflow 集成项目 已经注册,当 Scott 尝试再次注册它时会发生什么?是否有任何情况可以拒绝简对项目的分配?简对项目的分配是唯一有价值的结果吗?她会收到一封电子邮件吗?

    您可能已经看到在讨论场景时使用特定数据是多么容易。请记住:

    • 进行对话
    • 更重要
    • 捕捉对话
    • 更重要
    • 对话自动化

    如果你能同时完成这三件事,那就太赞了,但不要为了自动化而在对话上妥协。

    【讨论】:

    • 啊,我希望。尽管有敏捷宣言,但开发人员(包括我自己)很容易将注意力集中在工具上。这来自多年做错的经验,与做对的相比……我想这也是宣言的来源。在学习我们自己没有经历过的事情时,我们似乎总是妥协。
    【解决方案2】:

    “用户角色”是一个非常强大但难以掌握的概念。如果做得好,他们可以引导您实现简化、优化的用户体验。做错了,他们会占用时间并给团队成员一个主观的理由互相大喊大叫。

    查看http://www.agile-ux.com/2009/12/02/personas-in-agile-development-yes-we-can/ 以了解起点。有大量关于此主题的文献,但大多不是针对 BDD。

    我能给出的最重要的一条建议是,在定义你的角色时,重要的是要非常具体地说明什么让他们高兴/激励/挫败,但具体应该针对整个世界或计算一般 - 不要将这些东西与您的产品的特定方面或产品的个人愿望联系起来,因为否则 1) 角色很快就会过时并需要重新创建;2) 人最终将被用作主观武器促进您的个人愿望,而不是作为一种基于事实的工具来改进,为真实的人提供最好的产品。这说起来容易做起来难。

    【讨论】:

      【解决方案3】:

      很好为那里的角色命名,因为这样更容易理解故事;他们更多地参与了灵长类动物的大脑,因为它喜欢个体并且讨厌抽象。但是,您必须小心!尽量确保你使用的名字与你实际合作的人的名字不匹配——这会非常混乱——并且不要编码偏见——这个项目不是一个有偏见的东西,因为它不能有意见。也不要为不同的角色使用相同的名称;虽然现实中的人可能扮演着许多角色,但用户故事不应该这样混在一起,因为这很容易混淆。

      【讨论】:

        【解决方案4】:

        比较您的示例中的以下内容:

        鉴于 Scott 是项目经理,并且 stackoverflow 集成项目从未在系统中注册,当 Scott 注册 stackoverflow 集成项目并指定 Jane 为项目成员时,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();
        

        【讨论】:

          【解决方案5】:

          虽然您的方法具有指定的特定用户区,但对于领域专家来说更容易理解(因为 领域专家知道 *Scott_the_project_manager* 和他的任务)但我认为这种方法违反了Single_responsibility_principle:一个人可以有多个角色。

          Scott 也可能参与营销,*Magret_the_project_manager* 可能与 Scott 有不同的职责

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-02
            • 2016-11-18
            • 1970-01-01
            • 2011-12-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多