Google Groups

Re: [Capybara] Re: Database content not on web page when running with @javascript


jnicklas Apr 4, 2011 3:15 PM
Posted in group: Capybara
Just to clear this up a bit and explain the how an why a bit.

When Capybara runs under rack-test, everything happens in the same
thread of the same process. Capybara runs your stuff directly agains
your Rails app. What this means is that if you open a transaction in
cucumber, that same transaction is used within your Rails app, so if
you create a database record in Cucumber, it will show up in your
Rails app.

What happens under Selenium is this: Capybara starts up your Rails app
using a webserver (usually webrick or thin) in a *separate thread* of
the *same process*. ActiveRecord assumes that different threads are
used to handle concurrent requests, so it uses separate connections,
and thus separate transactions for each thread. What this means is
that if a record is created in Cucumber, that record is created in a
different transaction than the Rails app is running under, which means
it *won't* show up in the app.

Makes sense?

This leaves us with three possible solutions:

1. Switch off transactions entirely, truncate (empty out) the database
after each test
2. Switch off transactions only for those tests that use Selenium,
truncate the DB after those.
3. Make sure transactions are switched *on* and force Rails to use the
same transaction for all threads

If you just set up DatabaseCleaner with :truncation mode, number 1
will happen. This should do the job, but it's pretty slow. Also
transactions are nice, since there's less risk of crap data remaining
in your DB. Number 2 is what cucumber does out of the box. It works,
but it's kind of convoluted, and has a tendency to break every now and
then.

Number 3 is what José's hack is all about. The consequence of this, is
that if you use 3, transactions need to be switched *on*. You do not
need DatabaseCleaner for that, just set:

Cucumber::Rails::World.use_transactional_fixtures = true

Hope that clear up some confusion.

/Jonas

On Mon, Apr 4, 2011 at 5:25 PM, Larry <in...@stupidtuesday.com> wrote:
> Hi Jo,
>
> Thanks for chiming in. I wanted to test your theory and you are right:
> When I removed the fix Jonas supplied and changed the
> "DatabaseCleaner.strategy" from ":transaction" to ":truncation" in
> "features/support/env.rb" everything worked.
>
> I still don't fully understand all of this stuff, but I now have 2
> solutions which will hopefully be helpful to others.
>
> Thanks!
>
> -- Larry
>
>
>
> On Apr 4, 11:07 am, Jo Liss <jolis...@gmail.com> wrote:
>> On Mon, Apr 4, 2011 at 4:16 PM, Larry <i...@stupidtuesday.com> wrote:
>> > 3) I created /features/support/local_env.rb and inserted the code
>> > Jonas pointed me to athttp://pastie.org/1745020
>>
>> If I understand the purpose of that code correctly, you could also use
>> database_cleaner's truncation mode, right?  (Though it might be a
>> little slower, depending on the size of your test DB.)
>>
>> > This fixed my Cucumber/Capybara/Selenium problem, but could it ever
>> > cause problems in development or (more importantly) production mode?
>> > Do you think it would be a good idea to slap an "if Rails.env.test?"
>> > statement around the fix?
>>
>> As Jonas said, you shouldn't be doing this in production, but since
>> it's under features/support, it's only ever loaded by Cucumber, so
>> there's no need to check Rails.env.test?.
>>
>> Jo
>>
>> --
>> Jo Lisshttp://opinionated-programmer.com/