I've been trying to learn about Cucumber in Ruby and I thought that the best way to do that would be to make my own project. However, I'm wondering what constitutes a good "Given" clause.
As far as I understand, "Given" is basically a set up, "When" is the function under test, and "Then" is the expected result.
For example, let's assume I am making a Minecraft scenario based on an entity stepping in lava. My current G-W-T looks like this:
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
However, this "Given" step seems fairly 'off'. It doesn't make sense that I should have to be standing next to a block of lava for this scenario to work. Similarly - how would I write (and test) a GWT for a scenario that should always happen - for example, how could I ensure that as long as my entity remains in lava, that it will keep taking damage? I find it hard to write code that will test how long an entity has been standing in lava. How is the system to know how long the entity has been sat in lava? it seems to me that testing that sort of thing would require me almost writing the rest of the world in order to be able to say "this entity has been in the lava for x seconds, advance the simulation, how much hp have I lost"
Thoughts?
You don't have to rewrite the world. You just have to be able to fool your tests about the state of the world (in this case, time). The usual way to control time in tests is to stub.
I would write that scenario like this
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
and implement the time steps like this:
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
is kind of artificial, so you might fold that in to another step if it made sense. (I don't see an appropriate step in this case, but you might in a longer scenario.) When I wait 5 seconds
is perfectly appropriate to the domain, though.
Other niceties:
Given
is for conditions that are true before the scenario starts. One way to think about it is that time might have elapsed between when the Given
becomes true and when the actual scenario starts, during which other things might have happened that aren't relevant to the scenario.Given
that initializes your health. Minimizing such dependencies makes Cucumber steps more reusable. So as long as it doesn't hurt understandability (which I don't think it does in this case) just assert the final state at the end.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With