我一直在努力学习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;
思想?
答案 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
变为真实和实际情景开始之间可能已经过了一段时间,在此期间可能发生了与情景无关的其他事情。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 |