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

时间:2014-01-30 18:34:37

标签: ruby cucumber bdd acceptance-testing scenarios

我一直在努力学习Ruby中的Cucumber,我认为最好的方法就是制作自己的项目。但是,我想知道什么是好的"鉴定"子句。

据我了解,"鉴于"基本上是一个设置,"当"是被测试的功能,"然后"是预期的结果。

例如,让我们假设我正在制作一个基于堕入熔岩的实体的Minecraft场景。我目前的G-W-T看起来像这样:

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

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

思想?

4 个答案:

答案 0 :(得分: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

并实施以下时间步骤:

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

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

When I note the time有点人为,所以如果有意义的话,你可以把它折叠到另一个步骤。 (在这种情况下,我没有看到适当的步骤,但您可能会在更长的情况下。)When I wait 5 seconds非常适合域名。

其他细节:

  • 它简明扼要,适合使用第一人称。
  • Given用于在场景开始之前为真的条件。考虑它的一种方法是,在Given变为真实和实际情景开始之间可能已经过了一段时间,在此期间可能发生了与情景无关的其他事情。
  • 健康与站在熔岩旁边没什么关系,所以最好分开设置。
  • 测试你已经受到两次伤害(而不是你的生命值是8)需要在断言步骤和初始化你的健康状况的Given之间存在依赖关系。最大限度地减少这种依赖性使得Cucumber的步骤更加可重用。因此,只要它不会损害可理解性(在这种情况下我不认为它可以做到),只需在最后确定最终状态。

答案 1 :(得分:1)

有趣的问题!

  

"我不得不站在一旁,这没有任何意义   为这种情况工作的熔岩块。"

如果一个实体没有站在熔岩旁边,那么它就无法进入熔岩。你对自己的情景有什么看法?

现在关于测试对实体造成多大的伤害,如果你正在编写这个场景来测试实际的Minecraft游戏,那么你必须启用某种基于浏览器的计时器来计算监视器的数量。通过的时间(如果它在浏览器中播放)。这确实很尴尬。

但是,如果您正在编写自己的Minecraft版本,那么您可以编写方案,以便它将测试代码本身(即不测试在浏览器中运行的代码)。例如:

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
  And remains there for a unit of time
  Then the entity should take 2 damage

如果此测试正在执行您编写的代码,您将能够准确控制实体在熔岩区域中花费的时间(因此使用"时间单位& #34)

类似地:

Scenario: Take fatal damage when I remain standing 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
  And remains there for 5 units of time
  Then the entity should lose all health

当你说:

时,你是对的
  

"在我看来,测试那种东西需要我几乎写下其余部分   世界"

当你说"几乎"时,你的头上钉了一针。这种BDD方法的关键是采用渐进方法并尽可能地初始化以满足测试要求。一旦测试变为绿色,然后使用TDD实现模拟区域。

答案 2 :(得分:0)

如上所述,Give子句表示某种设置。我的大多数Given条款都可以在我的背景中找到。例如:

  Feature: A New User 
  Background:
    Given I am a new user

  Scenario: Writing a new Feature 
    And I add "text" to my new feature
    Then I should have a new feature named "feature.feature"

在这种情况下,后台验证“我是新用户”。在要素文件中,后台步骤在每个后续场景之前运行。

答案 3 :(得分:0)

我试图提高Fresh'的可读性。回答。我目前正在学习Gherkin(使用优秀的The Cucumber book)。代码可以从minecraft_gherkin_example

下载
Feature: Take damage when I stand in lava.

In minecraft, lava is bad for your health. 
    Every unit of time, damage reduces your health.

Scenario Outline: Step into lava
    Given my health level is <Health>
    When I step into the lava
        And I wait <LavaTime> unit of time
    Then my new health level is <NewHealth>
        And the outcome is <Outcome>

Examples:
  | Health | LavaTime |  NewHealth | Outcome   |
  |  10    |    1     |     8      | Alive     |
  |  10    |    4     |     2      | Alive     |
  |  4     |    1     |     2      | Alive     |
  |  2     |    1     |     0      | Game over |