我如何才能在黄瓜中最好地表达这种与时间相关的情景?

Dan*_*try 5 ruby bdd scenarios acceptance-testing cucumber

我一直在努力学习Ruby中的Cucumber,我认为最好的方法就是创建自己的项目.但是,我想知道什么是一个好的"给定"条款.

据我所知,"给定"基本上是一个设置,"当"是被测试的功能,"然后"是预期的结果.

例如,让我们假设我正在基于踩着熔岩的实体制作一个Minecraft场景.我目前的GWT看起来像这样:

Scenario: Take damage when I stand in lava.
  Given an entity is standing next to a block of lava with 10 health
  When the entity steps in the block of lava
  Then the entity should take 2 damage
Run Code Online (Sandbox Code Playgroud)

然而,这个"给定"步骤看起来相当'关闭'.我不得不站在一块熔岩旁边让这个场景发挥作用.同样 - 我将如何编写(并测试)一个应该经常发生的场景的GWT - 例如,我怎样才能确保只要我的实体保持在熔岩中,它将继续受到损害?我发现很难编写能够测试实体在熔岩中存放多久的代码.系统如何知道实体在熔岩中停留了多长时间?在我看来,测试那种东西需要我几乎写下世界其他地方,以便能够说"这个实体已经在熔岩中持续x秒,推进模拟,我失去了多少马力"

思考?

Dav*_*uth 2

你不必重写世界。您只需要能够欺骗有关世界状况(在本例中为时间)的测试即可。在测试中控制时间的常用方法是存根。

我会这样写这个场景

Scenario: Take damage when I stand in lava.
  Given I have 10 health
  And there is a block of lava next to me
  When I note the time
  And I step in to the block of lava
  And I wait 5 seconds
  Then I should have 8 health
Run Code Online (Sandbox Code Playgroud)

并执行这样的时间步骤:

When /^I note the time$/ do
  @start = Time.now
end

When /^I wait (\d+) seconds$/ do
  Time.stub(:now) { @start + 5.seconds }
end
Run Code Online (Sandbox Code Playgroud)

When I note the time有点人为,所以如果有意义的话,您可以将其折叠到另一个步骤中。(在这种情况下我看不到适当的步骤,但在更长的情况下您可能会这样做。)When I wait 5 seconds不过,它完全适合该领域。

其他细节:

  • 使用第一人称简洁且适合该领域。
  • Given适用于场景开始之前为真的条件。一种思考方式是,从成为Given事实到实际场景开始之间可能已经过去了一段时间,在此期间可能发生了与场景无关的其他事情。
  • 生命值与站在熔岩旁边没有太大关系,因此最好分步骤进行设置。
  • 测试您是否受到了两次伤害(而不是您的生命值为 8)需要断言步骤和Given初始化您的生命值之间的依赖关系。最大限度地减少此类依赖性使 Cucumber 步骤更具可重用性。因此,只要它不损害可理解性(我认为在这种情况下不会损害可理解性),只需在最后断言最终状态即可。