1

在他的文章中什么是故事?丹·诺斯(Dan North)提出了许多出色的观点。三个特别是:

  1. 场景标题应该说明有什么不同

    您应该能够并排排列场景,并仅使用标题来描述它们的不同之处。

  2. 场景应该根据给定、事件和结果来描述

    这是我在采用 BDD 的团队中看到的最强大的行为转变。只需让业务用户、分析师、测试人员和开发人员采用这种“给定/何时/然后”的词汇,他们就会发现一个模棱两可的世界消失了。

    并非所有场景都如此简单。有些最好表示为一系列事件,描述为:当[我做某事]时给定[某些上下文]然后[这发生]当[我做另一件事]然后[这个新事情发生]等等。一个示例是向导式网站,您可以在其中逐步浏览一系列屏幕以构建复杂的数据模型。只要您养成以这些术语思考的习惯,就可以将事件和结果的顺序混合在一起是完全合适的。

  3. 故事应该足够小以适应迭代

    关于如何做到这一点没有硬性规定,只要你把它分解成可证明的块。一般来说,如果有超过五六个场景,一个故事可能会通过将类似场景组合在一起来分解。

现在假设有人试图描述一些向导式功能的端到端验收测试(就像他在上面考虑的那样)。

  • 通过在使用向导功能开始时状态的不同来定义“场景”是很自然的(实际上这似乎符合他上面的第 1 点和第 2 点)——但列举通过向导的每条路径肯定是不合适的(从头到尾)以完全序列化的形式产生这样的独立场景?这不仅会产生很多场景,而且每个场景都会包含很多步骤(与 Dan 的第 3 点相反)——其中很多步骤会在场景之间重复,只是为了达到它们分歧的状态!

    Scenario: Make a successful booking
      Given that I am at the booking form
      When I do A
      Then I see B
      When I do C
      Then I see D
      When I try to book
      Then I see a successful message
    
    Scenario: Attempt to book, no availability
      Given that I am at the booking form
      When I do A
      Then I see B
      When I do C
      Then I see D
      When I try to book
      Then I see no availability
    
  • 另一方面,在向导功能的每个决策分支开始时为每个可能的状态定义一个场景会更有效—— “事件”只是将功能带到下一个步骤的单个步骤决策分支。但是,这不是将 SUT 移到堆栈中,因此我们将不再定义端到端验收测试,而是定义较低的顺序?此外,遵循和理解测试标准更不自然——这肯定会破坏 BDD 的全部意义吗?When

    Scenario: Do first step
      Given that I am at the booking form
      When I do A
      Then I see B
    
    Scenario: Do second step
      Given that I see B
      When I do C
      Then I see D
    
    Scenario: Make a successful booking
      Given that I see D
      When I try to book
      Then I see a successful message
    
    Scenario: Attempt to book, no availability
      Given that I see D
      When I try to book
      Then I see no availability
    

    如果走这条路,在我看来,将每个决策分支划分为单独的特征似乎更正确;然后在单个功能中仅考虑每个分支的那些场景——这仅强调了我关于 SUT 已向下移动堆栈的观点。

  • 也许这些端到端验收测试过于详细,整个向导(在这个阶段)应该更多地被视为一个黑匣子?但是,我不确定这如何帮助客户了解他们正在调试的内容——尤其是因为此功能的详细步骤是整个系统可接受性的关键。

将此类功能划分为场景的最合适方法是什么?

4

2 回答 2

2

我们大多数人遇到的巫师问题与我们表达事物的方式有关。当一个功能探索“如何”完成某件事时,它最终会变得冗长。我们应该关注的是我们为什么做事。

如果我们这样想,我们可以通过将整个向导封装为一个东西来完全否定这个问题。例如:

Feature: Fill in my tax form

Scenario: Fill in my tax form
  When I fill in my tax form
  Then my tax form should be filled in

然而,对于像这样复杂的东西,这可能是“高”的抽象。要添加更多细节,您必须将场景分成多个部分,并找到填写每个部分的原因。然后你使用原因(为什么)来编写你的场景。

如果我们回到税表并假装它只包含三个部分(为简单起见):身份、收入、支出。

现在我们可以编写如下内容:

Feature: Tax indentification
  As someoene who is taxed
  I need to provide proper indentification
  So I pay for my tax and not someone else's

Scenario: Provide indentification
  Given I am filling in my tax form
  When I provide indentification
  Then I should be asked about my income

我们可以用类似的东西探索悲伤的道路

  When I provide insufficient identification
  Then I should be asked for more indentification

等等

当我们实现了我们应该能够编写

Feature: Tax - provide income details
  ... 

Given I am filling in my tax form
And I have provided indentification
When I provide my income details
Then I should be asked about my expenses

我们可以重复探索悲伤路径的过程。请注意,Given 可以使用我们在实现身份阶段时创建的测试功能来实现。

这方面的艺术就是要找出你为什么要完成这个过程的每个阶段,以及你在完成这个过程的过程中给你到达的各种状态起什么名字。另请注意,功能中的任何地方都没有提及“如何”执行此操作

最后,这几乎是您谈到的第二种方法,特别强调“为什么”而不是“如何”。您可以选择抽象级别(即您将其分解为多少部分)并且您可以控制命名。语言和命名解决了您的可读性问题,特别是如果您考虑到可以从功能名称及其在文件层次结构中的位置等内容中提供的额外上下文。

于 2015-05-10T17:09:53.537 回答
1

恕我直言,每个可能状态的所有路径的覆盖都太详细了。BDD 帮助团队协作指定并进行深思熟虑的发现。因此,您应该关注关键示例(http://gojko.net/2014/05/05/focus-on-key-examples/)。

您的自动化测试通常有几个目的。基础是通过单元测试构建的,可帮助您确保正确构建产品。验收测试更上一层楼,可帮助您构建正确的产品。

于 2015-05-08T18:32:49.780 回答