Cucumber testing - the basics

19 views
Skip to first unread message

Oren Teich

unread,
Apr 15, 2009, 2:15:32 AM4/15/09
to Authlogic
Hi all,
I'm sure I'm missing something stupid, but sadly I'm having a hard
time getting cucumber to test my site.

Everything is behind a login page. I see the Authlogic::Testcase, and
that seems to be what I want, but I'm too clueless to figure out how
to actually use it.

So far, I've setup cucumber in 'features/support/env.rb' with:

require "authlogic/test_case"

Before do
activate_authlogic
end

A feature scenario like so:

Scenario: Workout graph
Given a registered user "test"
When I go to the workout page
Then I should see a list of workouts

And the steps as:

Given /^a registered user "([^\"]*)"$/ do |arg1|
UserSession.create(users(arg1))
visit '/workouts'
end

Then /^I should see a list of workouts$/ do
response.body.should =~ /New workout/
end

when I try and run cucumber, it's barfing on the "users" function:
undefined method `users' for #<ActionController::Integration::Session:
0x25909b4> (NoMethodError)

I'm running Rails 2.2.2, with Authlogic 2.0.4

Any guidance or pointers would be greatly appreciated!

thanks,
Oren

Loren Siebert

unread,
Apr 15, 2009, 2:32:57 AM4/15/09
to auth...@googlegroups.com
I think this is a cucumber + fixtures problem, not an authlogic problem.

Do you have your fixtures declared in your support/env.rb file?
#Seed the DB
Fixtures.reset_cache
fixtures_folder = File.join(RAILS_ROOT, 'spec', 'fixtures')
fixtures = Dir[File.join(fixtures_folder, '*.yml')].map {|f|
File.basename(f, '.yml') }
Fixtures.create_fixtures(fixtures_folder, fixtures)

In cucumber, I don't think you have the same access to fixtures as you
do in RSpec. But once you declare things as above, you can do
user = User.find_by_name(arg1)
in your steps.

You may want to check out the PDF beta version of the upcoming RSpec/
Cucumber book. That plus Ben Mabey's slide show at Mountain West
RubyConf might help, too.

-Loren

oomii

unread,
Apr 16, 2009, 8:54:27 AM4/16/09
to Authlogic
Hey Oren,

Just wanted to drop my 2 cents on the issue.

If your not completely married to fixtures, have a look at
factory_girl. Its got a 15 minute learning curve and in my opinion is
a superior way to get test data in the db on the fly.

Second, one of the things I like about cucumber is the ability to call
step definitions from a step definition. So when I'm testing and I
need to have a 'logged in user' in one of my scenarios heres how I do
it:

Given a user - which simply has factory_girl create me a user and
assign it to @user
And I am logged in - I have this step mapping to a series of other
steps, that take this 'user' through my login stack. go to login,
fill out the form from the variables stored in @user, press login, and
check that UserSession.find.should_not be_nil

When you go about things this way you get more coverage, your whole
stack is tested, and you can use it in an scenario that pre-defines a
@user.

Hope this helped a bit.

Joe

TheRailsWayOrTheHighway

unread,
Apr 16, 2009, 5:44:21 PM4/16/09
to Authlogic
Peculiarly, I am pursuing the same thing.

Instead of

Given /^a registered user "([^\"]*)"$/ do |arg1|
UserSession.create(users(arg1))
visit '/workouts'
end

I am doing

Given /^a registered user "([^\"]*)"$/ do |arg1|
@usr = User.create(:login => arg1, :password => "pswd")
puts("++++ Given a registered user #{@usr.login}, right before
UserSession.create")
UserSession.create(@usr)
end

This gets me past the UserSession.create statement. (FWIW,
UserSession.create returns true).


What is troubling, though, is that the AuthLogic magic isn't happening
in Cucumber. I go to my page (the New workout page in your example)
using script/server, but not in Cucumber.

My page controller (workout, in your example) has a

before_filter :require_user

but the UserSession.create statement in the step definition doesn't do
whatever AuthLogic needs done behind the scenes to allow this filter
to pass -- specifically, require_user is saying that the user is nil.


Looking at some of the other discussions in this group, I also chose
to add

require 'authlogic/test_case'
Before do
#setup :activate_authlogic
activate_authlogic
User.delete_all
end

to the end of features/support/env.rb, but it doesn't seem to help.

byrnejb

unread,
Apr 17, 2009, 11:52:06 AM4/17/09
to Authlogic

On Apr 16, 5:44 pm, TheRailsWayOrTheHighway
<HungerAfterRighteousn...@gmail.com> wrote:
> Peculiarly, I am pursuing the same thing.
>
> Instead of
>
>   Given /^a registered user "([^\"]*)"$/ do |arg1|
>     UserSession.create(users(arg1))
>     visit '/workouts'
>   end
>
> I am doing
>
>   Given /^a registered user "([^\"]*)"$/ do |arg1|
>     @usr = User.create(:login => arg1, :password => "pswd")
>     puts("++++ Given a registered user #...@usr.login}, right before
> UserSession.create")
>     UserSession.create(@usr)
>   end
>

If you visit the RSpec list with this problem you will probably be
advised to avoid creating user sessions directly and to authenticate
through the API of your app. I went through this learning curve with
both cucumber and authlogic last Christmas. Unless you are testing
authlogic itself I doubt very much that you need any addition to
env.rb, In any case place local customizations in another file such as
local_env,rb. "support/env.rb" is overwritten by script/cucumber and
you should run that script whenever cucumber is updated, which is
rather often.

Briefly, what I did in environment.rb is add this at the end.

# Add gem configuration calls here
config.gem 'authlogic'

That takes care of having authlogic available wherever you call it
inside your app and insures that your app will not start without it.

After setting up the application_controller and filter methods then
verify that one can authenticate via the UI. Once that works then set
up a helper step something like this:

When /user named "(.+)" authenticates/ do |name|
visit new_user_session_path
Then "see an authentication request message"
Then "enter the username \"#{name}\""
Then "enter the password \"#{name}-password\""
Then "press the authenticate button"
Then "see an authentication success message"
visit root_path
have_no_selector("#authentication_request")
end

Each of the Then clauses in that step are themselves steps that do the
appropriate things on the UI. I use a separate user factory step but
your approach works fine.


In your feature you would write this:

Scenario: A user can visit the workouts page
Given a user named "mike"
And the user named "mike" authenticates
When they visit the "workouts" page
Then they should see "something to do with workouts"

Despite the wordiness, this approach of calling steps from steps keeps
each step very small and easy to debug or refactor as the UI is
elaborated. Diving authentication through the UI tests the effect of
each change, including those made to routing as new controllers are
added, which can have surprising effects on authentication, I caught
many errors in my authentication and authorization logic as I built
additional bits, none of which would have been found until much later
had I bypassed the UI and created the user session directly.

HTH

TheRailsWayOrTheHighway

unread,
Apr 20, 2009, 11:44:56 AM4/20/09
to Authlogic
Excellent! Thank you for the pointers; it's working for me now.
Reply all
Reply to author
Forward
0 new messages