Forum: RSpec Cucumber speed tips

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mischa F. (Guest)
on 2008-12-27 10:10
(Received via mailing list)
As some of us have been using cucumber for quite a while now, I may not
be
the only one wishing his many steps ran a bit faster.

Let's try to put together a quick FAQ for people looking to speed up
their
steps.

Here's my ideas:

1) Consolidate steps
You only need to test login for each login case, not for each time you
are
testing some sort of logged in functionality.
In most cases you can just post to sessions/create rather than filling
in a
login form.

1a) Don't use GivenScenario
Instead, make one step that will quickly do what the scenario you want
to
start at the end of does. E.g. rather than fill in a form and post to a
controller to create an object, just create the object in its own step.

2) Use the profiler format
I've only tried this a few times, but the profile formatting appears to
be
useful.


Anybody else have any tips?

M
Ben M. (Guest)
on 2008-12-27 19:54
(Received via mailing list)
On 12/27/08 1:08 AM, Mischa F. wrote:
> are testing some sort of logged in functionality.
> I've only tried this a few times, but the profile formatting appears
> to be useful.
>
>
> Anybody else have any tips?

3) Seed your database in your support files.  For static data that will
be used over and over again you can save time by only inserting it once
in your DB at the start of the run.  For example in env.rb you could
say:

unless ZipCode.count == 79851
  puts "Loading all the zip code data..."
  ....
end
Josh K. (Guest)
on 2008-12-28 18:32
(Received via mailing list)
On Sat, Dec 27, 2008 at 12:52 PM, Ben M. <removed_email_address@domain.invalid> 
wrote:
>> 1) Consolidate steps
>> 2) Use the profiler format
>> I've only tried this a few times, but the profile formatting appears to be
>> useful.
>>
>>
>> Anybody else have any tips?
>
> 3) Seed your database in your support files.  For static data that will be
> used over and over again you can save time by only inserting it once in your
> DB at the start of the run.  For example in env.rb you could say:


4) Distribute your scenarios across multiple processes using TestJour
(http://github.com/brynary/testjour)


--
Josh K.
phone: 509-979-1593
email:  removed_email_address@domain.invalid
web:    http://joshknowles.com
Luke M. (Guest)
on 2009-01-04 03:43
(Received via mailing list)
On Dec 27, 2008, at 3:08 AM, Mischa F. wrote:

> You only need to test login for each login case, not for each time
> you are testing some sort of logged in functionality.
> In most cases you can just post to sessions/create rather than
> filling in a login form.

I also wanted to speed up the "Given I am a logged in user" type of
thing, as you suggested, but took a different, faster approach which
may also work for you. I set a cookie to auto-login the user on the
next request. Implementation as a gist http://gist.github.com/42973
and below. -Luke

features/steps/users_steps.rb:

Given "I'm a logged in member" do
   @me = create_adult
   logged_in_as @me
end

features/support/env.rb:

class Cucumber::Rails::World
   ...
   def logged_in_as(user)
     cookies['integration_test_user'] = user.id.to_s
   end
   ,,,
end

app/controllers/application.rb

class ApplicationController < ActionController::Base
   ...
   before_filter :login_integration_test_user, :if => lambda
{ Rails.env == 'test' }
   ...
   def login_integration_test_user
     return true if cookies['integration_test_user'].blank?
     integration_test_user_id = cookies['integration_test_user'].to_i

     if integration_test_user_id != current_user.id
       reset_session
       self.current_user = User.find(integration_test_user_id)
     end

     cookies['integration_test_user'] = nil
   end


--
Luke M.
removed_email_address@domain.invalid
http://www.lukemelia.com/
Luke M. (Guest)
on 2009-01-04 03:57
(Received via mailing list)
On Dec 28, 2008, at 11:30 AM, Josh K. wrote:

> 4) Distribute your scenarios across multiple processes using TestJour
> (http://github.com/brynary/testjour)

To provide a little more info (Josh and I work with Bryan, who created
testjour): we have a cucumber suite currently consisting of 5835 steps
that takes a bit under 20 minutes to run without testjour.

Running it via testjour with 2 local slaves and 6 remote slaves (2 mac
minis and a Mac Pro), the run completes in about 4 minutes.

testjour is still a little raw, but I already would not want to work
on a large product without it.

Luke
--
Luke M.
removed_email_address@domain.invalid
http://www.lukemelia.com/
Ben M. (Guest)
on 2009-01-04 04:14
(Received via mailing list)
On 1/3/09 6:41 PM, Luke M. wrote:
> next request. Implementation as a gist http://gist.github.com/42973
>
> class ApplicationController < ActionController::Base
>       self.current_user = User.find(integration_test_user_id)
>     end
>
>     cookies['integration_test_user'] = nil
>   end


The downside with this approach is that it only works with the rails
webrat adapter.  One solution which I have been meaning to do is to
create a UsersSessionManager.  The manager would be responsible for
logging in all the various roles you use in your app with different
webrat sessions (and then caching them.)  You could then swap out which
session you would be using in your steps...

So you could then do something like:

logged_in_as 'Admin' do |session|
  session.click_link 'Foo'
...
end

Or..

Given /^I am logged in as an '(.+)'$/ |role|
   login_as role
end

The 'login_as' would swap out the session that the World object uses so
the next steps would be using the appropriate session.

WDYT?

-Ben


-Ben
Luke M. (Guest)
on 2009-01-04 05:44
(Received via mailing list)
On Jan 3, 2009, at 9:12 PM, Ben M. wrote:

> session.click_link 'Foo'
> so the next steps would be using the appropriate session.
>
> WDYT?

In general I like the idea, Ben. At weplay, we use webrat to drive
rails and selenium, and logged_in_as method has the following
implementation in the Selenium world:

   def logged_in_as(user)
     visit login_for_test_path(user)
   end

where login_for_test_path is is a named route defined only for the
selenium environment that provides a "quick" login of a given user.

Would the solution you're thinking of help with this? I'm not sure how
you would "cache" a selenium session.

--
Luke M.
removed_email_address@domain.invalid
http://www.lukemelia.com/
Ben M. (Guest)
on 2009-01-05 02:10
(Received via mailing list)
On 1/3/09 8:36 PM, Luke M. wrote:
>>
>>
>     visit login_for_test_path(user)
>   end
>
> where login_for_test_path is is a named route defined only for the
> selenium environment that provides a "quick" login of a given user.
>
> Would the solution you're thinking of help with this? I'm not sure how
> you would "cache" a selenium session.

I'm by no means a Selenium expert so I may be making some incorrect
assumptions.  I thought that it was possible with Selenium to have
different sessions open concurrently for the same selenium server. (i.e.
have more than one SeleniumDriver/browser instance running against the
same server but with different session ids.)  Is that not possible?

-Ben
Luke M. (Guest)
on 2009-01-06 06:47
(Received via mailing list)
On Jan 4, 2009, at 7:08 PM, Ben M. wrote:

> I'm by no means a Selenium expert so I may be making some incorrect
> assumptions.  I thought that it was possible with Selenium to have
> different sessions open concurrently for the same selenium server.
> (i.e. have more than one SeleniumDriver/browser instance running
> against the same server but with different session ids.)  Is that
> not possible?


Not that I know of, but now that you mention it, seems like it would
be pretty cool. Anyone else on the list done this?
--
Luke M.
removed_email_address@domain.invalid
http://www.lukemelia.com/
Mischa F. (Guest)
on 2009-01-06 08:31
(Received via mailing list)
Josh, Ben & Luke --

This is great stuff, thanks a bunch. Over at CaptainU we are probably
going
to get into the thousands in the next few weeks or so, so speed is a
serious
issue. I'm going to work on a longer blog post about this, will let you
guys
know when finished.

Best,

M
This topic is locked and can not be replied to.