为长篇故事编写 BDD 的最佳方法

Best ways to write BDD for long stories

我们最近开始使用 BDD 来编写我们的需求。这真的很有帮助,它使分析师和开发人员之间的沟通变得更加容易。 (结合用户界面和旧学校要求)

现在我们正在考虑用 BDD 编写我们的测试用例。当我在网上搜索最佳实践时,我看到了很多关于如何编写它的不同变体。

有一些例子,例如:

问题是几乎所有示例都是针对非常简单的情况,另一方面我们想编写包含多个操作、多个系统输出(警告、错误等)和多个输出的场景。

我们正在尝试找出为以下场景编写 BDD 的最佳方法:

我们希望用户执行以下操作:

之所以说这么长的故事,是因为这是一种可能发生的常见情况,我们希望确保用户能够回到快乐的道路上。

您认为使用 BDD 处理这种情况的最佳方法是什么?

处理长故事的最好方法,如在长场景中,使用 BDD 是不做的。

您想做的是专注于应该实现的业务价值。其余的,授权,警告和类似的,应该在步骤的实施中处理,而不是在功能文件中明确。用户是否获得授权可能不是业务代表真正关心的事情。他们只是假设执行特定任务时会出现这种情况。

您描述的是使用 BDD 作为测试工具。 BDD 从来就不是一个测试工具,因此如果它是您真正需要的自动化测试,则不适合。

有一些博客 post 您可能有兴趣阅读更多关于此的内容:

我将尝试重新表述您在这里的要求,希望它能解决一些问题。

We have recently started using BDD to write our requirements... Now we are thinking about writing our test cases with BDD.

我们最近开始使用示例来阐明我们的要求...现在我们正在考虑将这些示例自动化。

When I search online for the best practices I see a lot of different variations on how to write it.

当我在线搜索时,我看到很多不同的背景、事件和结果。

(不仅仅是在写作中;在导致写作的对话中。这就是为什么会出现差异;因为对话真的很模糊。)

Problem is almost all examples are for very simple cases

问题是在过去,像我这样的早期采用者使用登录之类的东西作为例子。

我们这样做是错误的。简单的示例实际上并不能帮助您理解 BDD。美妙之处在于,当我们与了解问题的利益相关者(例如,他们可能是安全或基础设施专家;它不仅仅适用于业务专家)交谈时,我们 了解到 某物。这是 a talk 关于我们在 BDD 早期做错的事情;你遇到了其中一些的成本。对不起。

我写了 a whole blog post BDD 的三个方面:探索、规范和实例测试。大多数人关注其中的第二个和第三个,但第一个是隐含的。探索很重要,围绕场景进行对话是一种非常便宜的方式!

We'd like to write scenarios that includes multiple actions, multiple system outputs (warnings, errors etc.) and multiple outputs... The reason we have such a long story is that this is a common scenario that can happen and we want to make sure that users are able to go back to happy path.

我们想检查完整的客户旅程,以确保我们的系统至少可用,无论发生什么情况。

因此,如果您想使用像 Cucumber 这样的 BDD 工具来编写一个完整的、全栈的、自动化的客户旅程,而不是一个行为方面的单个示例(我们称之为场景),那么...这不是 BDD。

但是,仍然是一个非常好的主意。这不是 BDD,但这并不意味着它是一件坏事。我曾与许多已经这样做并从中受益的组织合作。 (也许它应该有一个名字。)

以下是我根据那次经历可以给你的提示和技巧:

  • 不要不要使用这些作为回归测试!尝试走完每一段旅程需要付出 2^n 的指数级努力;算了吧。选择几个旅程(每个理想会话 3 个似乎很典型)并尝试选择不同但典型的客户选择。不要使用这些来测试边缘情况。您只是在检查您的主要客户旅程是否仍然连接在一起。

  • 声明式优于命令式仍然是规则。避免谈论 UI;根据每个阶段所取得的成就来描述旅程。

  • 如果你能做到这一点,你就可以在较小的场景中重用你的步骤。将您的客户旅程(有时称为 "smoke tests")放在一个单独的地方,即使它们 运行 在构建的同一部分。 运行 全部先解决,直到您不再需要为止(一个月左右的这些破坏将使团队解决根本原因、环境问题等!)。

  • 要具体。不只是 "a user";是苏,路边的那个女孩正在她的地图上使用您的多边形来尝试发现她尚未捕获的神奇宝贝。具体的故事真正抓住了人们的想象力,使旅程令人难忘。如果可以,让不同的旅程匹配不同的角色。

  • 通常,一个场景的 "then" 会形成具有不同行为方面的另一个场景的 "given"。如果将它们串在一起,不用担心 "then"。如果您要在下一步中使用它,则无需检查结果。例如,如果一个菜单需要显示一个特定的选择,不要检查这个选择;只需使用它并假设它在那里。 UI 支票可能很昂贵,而且由于这些较长的旅程,我们应该在一个通常会经过的地方。如果它们不是,那么在我们弄清楚它们为何损坏的那段时间添加缺失的步骤是非常微不足道的。通常这些都是集成测试。在较长的场景套件 运行.

  • 之前检查特定服务是否已连接等
  • 如果您的常见客户旅程包括用户感到困惑、做错事或以其他方式浪费他们的时间,请更改您的 UI。用户体验专业知识仍然非常非常重要,并不是 BDD 的真正组成部分,因为与 [=111= 的比较和建议相比,很难为 "easy" 或 "forgiving" 提出具体示例]. BDD 不是灵丹妙药。

  • 将围绕完整客户旅程的对话中的工件写下来,甚至散布在办公室的整面墙上是很常见的。然而,自动化版本通常是在完成较小的场景并且功能正常运行后创建的。

  • 完整的端到端客户旅程与涵盖边缘案例等行为方面的较小场景之间通常存在重复。端到端的旅程提供快速反馈并确保没有人的时间被浪费;较小的场景提供有关系统应如何运行的文档。在这种情况下复制是可以的。

如果您决定希望这是一个完整的旅程,这就是我希望看到的那种东西(我在这里所做的就是 "declarative vs. imperative" 东西):

Given Sue's registered to catch Pokemons  
And Bulbasaurs, Koffings and Pikachus were caught in Trafalgar square this year
When she filters for Pokemons caught between January and July
And adds a filter for "Poison" traits
And filters for "Bulbasaur"
When she searches for Pokemons
Then she should be asked to select an area of the map
When she selects an area around Trafalgar Square
Then she should be shown the Bulbasaur density
But not the Pikachu or Koffing density.

使用具体的例子。当它实际上包含现实的想法时,更容易理解和看到上面的缺陷,或者根据我对 Pokemon Go(我还没有玩过)的理解。这是这些旅程和较小场景之间的共同点。

您还会看到有很多很多 "whens",而且它们都相互影响。如果我们讨论行为的单个方面,那么每个方面都将以 "given" 开头,概述之前发生的事情的背景,而允许下一个 "when" 的结果将是 "then" .在这种情况下,尽管我们将它们链接在一起。 "whens" 的不间断序列在这类旅程中非常常见并且完全可以,只要您尊重这是 而不是 关注行为的单一方面,也没有提供示例它的(所以它不是真正的 BDD)。 "Thens" 当结果是旅程的重要组成部分时,就会出现旅程中期,特别是提供用户必须具体回应的非特定指导。

不要将这些自动化,因为存在误解!自动化的客户旅程代表了一项重大投资(尽管一旦您拥有涵盖相同功能的较小场景,它们就很容易组合在一起)。首先让功能发挥作用,并将其展示给相关利益相关者。您不想在可能会随着学习和反馈而改变的事情上投入大量资金。

希望这对您有所帮助,感谢您让我考虑清楚!