Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a login step prior to scenario outline in cucumber

Tags:

cucumber

I'm using cucumber with webrat/mechanize to test a PHP site and I'm trying to improve the speed the tests run by avoiding running unnecessary steps.

I want to use a scenario outline to check a whole lot of pages are accessible/protected depending on the user who is logged in:

Scenario Outline: Check page access is secure
  Given I am logged in as "<user>"
    And I am on <page>
  Then I should see "<message>"
Examples:
  |user  |page      |message                |
  |admin |home page |Welcome to my site     |
  |admin |admin page|Site administration    |
  |editor|home page |Welcome to my site     |
  |editor|admin page|Access denied          |
  |guest |home page |Please login           |
  |guest |admin page|Access denied          |
  ...

This works, but given I have 10 roles and hundreds of pages to check, there is a lot of overhead in running the login step every time the outline runs.

I'm wondering if there is a way to run the login step once for each role, then visit each page in turn without needing to login every time. i.e run "login, visit 1, visit 2, visit 3" instead of "login, visit 1, login, visit 2, login, visit 3".

I've tried using hooks, and Background, but can't seem to find an approach that works. Is this possible?

like image 627
simoncoggins Avatar asked Sep 01 '10 03:09

simoncoggins


1 Answers

Instead of putting all the information about what is accessible/protected in the feature, consider putting them in the step defs (even better would be to use the definitions in your application, but that isn't easy if your app is not in process)

If you can live with a feature that is as abstract as

Given I am an admin
Then I should be able to access admin pages

Then you can do all the work much more efficiently in step defs

Following is just a code sketch to give some idea of what you can do ...

# step def
module AccessHelper
  AdminPages = {
    {page: ..., msg: ...
    ...
  }
  def login_as ... ; end
  def correct_message? msg ...; end
  def check_admin_access_for user
    @errors = []
    login_as @I
    AdminPages.each do |page|
      visit page[:path]
      errors << page unless correct_message?
    end
  end
end
World(AccessHelper)

Then "I should be able to access admin pages" do
  check_admin_access_for @I
  @errors.should be_empty
end

You can of course expand this using the full power of ruby to meet you particular needs. The fundamental idea is that you can always take several cucumber actions and abstract them into one cucumber action.

Hope thats useful

like image 130
diabolist Avatar answered Oct 02 '22 12:10

diabolist



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!