在他的文章What's in a Story?中,Dan North提出了许多优点。特别是三个:
情景标题应该说明什么不同
您应该能够并排排列场景,并仅使用标题描述它们之间的区别。
应根据Givens,Events和Outcomes
描述场景这是我在采用BDD的团队中看到的最强大的行为转变。只需让业务用户,分析师,测试人员和开发人员采用“给定/何时/当时”这一词汇,他们就会发现一个模糊的世界消失了。
并非所有情况都如此简单。有些被最好地表示为一系列事件,描述为:给[某些上下文]当[我做某事]然后[这发生]当[我做另一件事]然后[这个新事物发生] 等等。一个示例是一个向导式网站,您可以在其中逐步浏览一系列屏幕以构建复杂的数据模型。只要你养成用这些术语思考的习惯,将事件和结果的序列混合在一起是完全合适的。
故事应足够小,以适应迭代
关于你如何做到这一点,没有严格的规则,只要你把它分解成可证明的块。一般情况下,如果有超过五个或六个场景,可以通过将类似场景组合在一起来分解故事。
现在假设有人试图描述某些向导式功能的端到端验收测试(如上所述)。
定义"场景"很自然。通过一个人使用向导功能开始时的状态有何不同(事实上,这似乎符合他上面的#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
另一方面,在每个决策开始时为每个可能的状态定义一个方案会更有效率向导功能中的分支以及When
"事件"只是将功能带到下一个决策分支的单一步骤。但是,这不会将SUT向下移动到堆栈中,因此我们不再定义端到端验收测试,而是定义较低阶的某些东西?此外,遵循和理解测试标准更不自然 - 这肯定会破坏BDD的整个观点?
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向下移动的观点。
也许这些端到端验收测试过于详细,整个向导应该(在这个阶段)被视为黑盒子?我不确定这有助于客户了解他们正在调试的内容,特别是因为此功能的详细步骤是整个系统可接受性的关键。
将此类功能划分为方案的最合适方法是什么?
答案 0 :(得分: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。
这一切的目的都在于找出为什么要完成整个过程的每个阶段,以及当你完成整个过程时,你给出的各个州的名字。另请注意,在功能
中的任何位置都没有提及“如何”执行此操作最后,这几乎是你谈到的第二种方法,另外强调'为什么'超过'如何'。您可以选择抽象级别(即您将其分成多少部分),然后您可以控制命名。语言和命名解决了您的可读性问题,特别是如果您考虑了可以从功能名称及其在文件层次结构中的位置等方面提供的额外上下文。
答案 1 :(得分:1)
恕我直言,每个可能状态的所有路径的覆盖范围都太详细了。 BDD帮助团队协作指定并进行深思熟虑的发现。因此,您应该关注关键示例(http://gojko.net/2014/05/05/focus-on-key-examples/)。
你的automated tests have often several purposes。基础是通过单元测试构建的,可帮助您确保正确构建产品。验收测试更上一层楼,帮助您构建正确的产品。