我是BDD的新手,正在尝试使用它来充实新项目上的功能规范。
您在网上看到的大多数示例在细节方面看起来都很简单明了。我正在努力了解要包含在方案中的重要内容和不应包含的内容。
例如,给定标题,例如:用户登录
方案1:用户使用有效的凭据登录
给出,显示“登录”页面
何时用户输入用户名和密码
然后用户提交请求
然后,将用户定向到主页
我不明白的是,如果用户已被管理员禁用或由于密码尝试失败次数过多而被锁定等,该怎么办?这些是单独的情况吗?如果是,方案1 是否需要指出该用户未被禁用并且未被锁定?
在后端发生的事情如何-即客户端希望系统登录每个用户登录-包括在场景中吗?我读过的大多数内容听起来都听起来好像BDD应该专注于与系统的用户交互。
如果您确实包括后端登录之类的东西-那么在失败的登录尝试中增加失败的登录计数器会怎样?这似乎是更多技术细节-如果需要锁定功能,该文件在哪里记录?
正如您所看到的,我很难决定关于BDD方案范围的界限。
感谢您帮助我们更好地理解!
答案 0 :(得分:3)
我们应该在场景中包括哪些背景?
我发现将场景不视为测试是有帮助的,而可以作为活泼的文档来帮助说明系统的行为方式以及为什么这样做很有价值。
如果您可以说在第一种情况下用户没有被锁定,也没有被禁用,那么您无需包括这些步骤。
对于诸如使用有效的已启用帐户登录的事情来说,这是显而易见的,但是对于诸如交易者保持在其交易限制之内,胎儿心跳保持健康状态或没有发表评论之类的事情则可能不是这样。尚未达到报告阈值。您可以决定是否务实地包括这类上下文。
我更愿意将不更改或不经常更改的文档(如核心领域概念)移到方案之外。可能是在方案文件顶部的摘要中,也可能是新加入者在编码之前必须阅读的团队Wiki。不必在场景中。
(显然,在任何故障情况下,您都需要包括导致故障的上下文!)
副作用和其他结果如何?
所有结果之所以如此,是因为它们在某个时刻变得可见或在场景所涵盖的行为范围之外具有影响。
例如,当我从自动提款机取钱时,我的帐户也记入借方。我可能不会将其视为行为的一部分,但是必须做到这一点。那是因为场景中还有另一个利益相关者-银行。
或者,也许,当弗雷德(Fred)的微波炉退款时,微波炉又重新投入库存,库存数量增加。弗雷德(Fred),耕作操作员和库存控制员都是这里的涉众。
在我们要向日志中添加某些内容的情况下,有一个利益相关者将把这些日志用于其他内容。认识到这种价值可以帮助我们弄清为什么要采伐,并描述利益相关者的POV认为有价值的结果。
如果结果可以独立运送并且仍然有价值,那么它们可以出现在单独的场景中。我对此非常务实,因此我可能会将它们放在相同的场景中,然后在“库存控制”场景的数量意味着它可能应该有自己的功能文件时再将其重构。
如果结果不能单独运输(通常在任何事务处理中都是这样),我希望看到这些结果至少在一种情况下同时出现,以使它们显而易见有关。它们不必出现在每种情况下。例如,一旦我们编写了这样一种方案,即用户没有资金,因此他们的帐户不会记入借方,我们可能就不必在任何其他现金提取中再次提及该帐户了故障场景。
从多个利益相关者的角度来看,还与BDD概念“外部-内部”有关,在该概念中,我们添加到系统中的所有行为都是为了通过某个界面为某些利益相关者提供价值。
与其他用户或与时间的互动如何?
有时-非常偶尔-我们需要多个何时来描述正在发生的事情,并且增加登录计数器的示例是一个很好的例子。
登录计数器的值仅是 ,它会在3次尝试后禁用该帐户。它本身没有任何价值。这是一个实现细节。如果我们将其变成场景中的结果,那么我们将自己与该实现耦合在一起,那将不是很好。因此,有两种情况-一种描述登录计数器的工作方式,另一种显示其为什么有价值的理由-感觉不对,因为其中一种没有描述有价值的行为:
Given Clarence logged in successfully last time
When Clarence enters his password incorrectly
Then the login counter should be incremented.
Given Clarence's login counter was incremented twice
When Clarence enters his password incorrectly
Then his account should be disabled.
Y。我们不要那样做。
该计数器中的唯一值来自克拉伦斯的行为与克拉伦斯的未来(或过去)行为的相互作用。这样我们就可以像这样:
Given Clarence logged in successfully last time
When he enters his password incorrectly
And enters his password incorrectly
And enters his password incorrectly
Then his account should be disabled.
当然,这有点大话,所以我们可能会说:
Given Clarence logged in successfully last time
When he enters his password incorrectly 3 times
Then his account should be disabled.
我们可以这样做,因为这是同一件事。虽然有些互动涉及发生的不同事情(“时间流逝”是我经常遇到的另一种互动。)
Given Clare is editing trade 12345
When Stephen edits and saves that trade
And Clare tries to save that trade
Then she should be told that Stephen has already edited it.
在这种情况下,克莱尔的互动方式与史蒂芬的互动方式有所不同,因为她的保存尝试失败。
请注意,此处使用 tries 表示失败;我如何使用假设的另一个例子。如果未显示 tries ,我们可以认为该事件已成功。替代方法是:
When Clare saves the trade successfully
除非成功的结果令人惊讶,而不是正常现象,否则这将导致重复,因此我更愿意对默认值不使用任何尝试,而对失败则使用尝试。从自动化的角度来看,它们之间的区别很重要,因为它使我们能够执行诸如将自动化的工作流程移至错误页面而不是确认页面的操作。
它的阅读效果也很好。这几乎就是为什么我们仍然尝试使用这些英语工具的原因。