Mumfi
Mumfi

Reputation: 425

Naming step definitions used with 2+ keywords (e.g. Given + Then)

Consider this feature snippet:

Given the date is '2022-01-01'
...
When the date is '2022-01-31'
...

One identical step but used with two different keywords. I haven't find much discussion about the naming convention in this case. I'd love for people to give their input.

The three main approaches I suppose are:

Name method with first keyword you use. If you need to use it again, just do it and ignore the fact that the method contains "Given" in its name

[Given(@"the date is '.*'")]
[Then(@"the date is '.*'")]
    public void GivenTheDateIs(string date)
    {
        ...
    }

Use appropriate keyword in method name and create new method if needed more than once

[Given(@"the date is '.*'")]
    public void GivenTheDateIs(string date)
    {
        //same code
    }

[Then(@"the date is '.*'")]
    public void ThenTheDateIs(string date)
    {
        //same code
    }

Don't use keyword in method name

[Given(@"the date is '.*'")]
[Then(@"the date is '.*'")]
    public void TheDateIs(string date)
    {
        ...
    }

Which one do you use and why?

Upvotes: 0

Views: 386

Answers (1)

diabolist
diabolist

Reputation: 4109

Given is for setting up state
When is for doing something
Then is for evaluating results

In English at least tense differentiates

Given - past tense
When - present tense
Then - future tense

Generally When's are going to be done inefficiently.

With a UI a When will involve a browser interaction. Often a Given that does the same thing can be done more efficiently without that browser interaction. With an API the When will be done by a request/response cycle. Again a Given can do the same thing without the request/response.

For example consider adding the behaviour registration. First you would do

When 'I register' do
  fill_in name, with: "Fred"
  ...
  submit_form
end

But for you given you might do

Given 'I am registered' do
  User.create(
    name: "Fred"
    ...
  end
end

which is much much faster.

You will use When I register only a few times in your application

You will use Given I am registered (in some form or other) for almost every user interaction you write a scenario for.

For the above example the Then is

Then 'I should be registered' do
  # check UI for proof or registration
end

So Given's, When's and Then's are not only different in their context and tense, but also they are different in their implementations and their frequency of use.

The idea that a Given could be identical to a When or Then just reflects a lack of understanding and precision in your use of language for your scenarios and code for the implementation of your step definitions.

Of course you are allowed to write Cukes without this precision and control, but you don't need to, and you will gain alot if can write precisely enough that you never have to worry about the difference between a Given, When or Then

Caveats: Answer is opinionated, but question is an excellent one in my opinion. All code and examples are Ruby. All the examples are crude and simplistic. Putting lots of code in step def and calling the database directly in test code is poor practice.

Upvotes: 2

Related Questions