Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write cucumber for rails (Best practice). Feature and Steps

I'm currently trying to learn cucumber and how to properly utilize it. When searching for best practices most of the old way is described and I haven't really found a good guide. I read about the new way to do it but I have some problems with the best practice.

The following is some basic cucumber scenario I have been working on.

Scenario: Unsuccessful login
    Given a user has an account
    When the user tries to log in with invalid information
    Then the user should see an log in error message

Scenario: Successful login
   Given a user has an account
   When the user logs in
   Then the user should see an log in success message
   And the user should see a sign out link

Scenario: Successful logout
   Given a signed in user
   Then the user logs out
   And the user should see an log out success message

I wonder if this is ok? I have problems if I should write it as "I visit" or "the user visit" or "he visit" Basically what is preferred?

Secondly I wonder how I should formulate the following:

Scenario: Visit profile of user
  Given a user
  And a second user
  When the user visit the user profile
  Then the user should see the name of the user

Scenario: Visit profile of another user
  Given a user
  And a second user
  When the user visit the second users profile
  Then the user should see the name of the second user

This is just something I put together but I feel that it's not the best way. I run into problems in my step definitions files. How would you define the steps to handle the scenarios? I wanted to write something more general, but maybe it's not really possible? Should I have a @second_user attribute or what do you suggest?

def user
  @user ||= FactoryGirl.create :user
end

Given /^a signed in user$/ do
  user
  sign_in(@user.email, @user.password)
end

Given /^a user has an account$/ do
  user
end


When /^the user logs in$/ do
  sign_in(@user.email, @user.password)
end

When /^the user logs out$/ do
  click_link ('Sign out')
end

When /^the user tries to log in with invalid information$/ do
  sign_in("incorrect-email", "incorrect-password")
end

Then /^the user should see a sign out link$/ do
  page.should have_link('Sign out')
end

Then /^the user should see an log in success message$/ do
  should have_success_message('Signed in successfully.')
end

When /^the user should see an log out success message$/ do
  should have_success_message('Signed out successfully.')
end

Then /^the user should see an log in error message$/ do
  should have_error_message('Invalid email or password.')
end

Thanks for helping me out!

like image 253
Jon Andersen Avatar asked Nov 21 '12 00:11

Jon Andersen


1 Answers

I have problems if I should write it as "I visit" or "the user visit" or "he visit" Basically what is preferred?

I think using something like "when a user visits" is going to be more generic and will be more readable as you don't have to keep thinking "who is 'he' ?" if you are reading the tests, what really matters is that you stick to some convention in all your files so that you don't get confused.

For your second question about creating a @second_user or not, I think you shouldn't because this user is not exactly part of your scenario as much as it is a data setup, and I think the best way to handle data setup is to use pickle with cucumber, it basically allows you to create models in your cucumber without having to keep them as variables with you, there is a great cast on RailsCast that explains a lot.

so I would do this using pickle

Scenario: Visit profile of another user
  Given a user exists with name: "Mike", username: "mike"
  And a signed in user
  When the user visits the profile of "mike"
  Then the user should see 'Mike'

then you could define

When /^the user visits the profile of (.+)$/ do |username|
  visit("/#{username}") # I am assuming here usernames are unique and the profile url is "/:username"
end
like image 135
Khaled Avatar answered Nov 15 '22 05:11

Khaled