Skip to content

error in after(:each) block causes per-test transaction to not get rolled back (was: Nested transactions causing Postgres woe) #58

Closed
wjessop opened this Issue May 22, 2010 · 28 comments

6 participants

@wjessop
wjessop commented May 22, 2010

I'm using rspec-rails 2.0.0.beta.8 with a rails 3 beta app (just upgraded from rails 2.3.5) and postgres. I have a bunch of rspec tests that were previously working with rspec 1.3/rails 2.3.5. However upgrading to this latest rspec seems to cause issues because it is trying to open nested transactions which postgres doesn't support, this the console output from the test run:

WARNING: there is already a transaction in progress
WARNING: there is already a transaction in progress

I have configured rspec-rails to use_transactional_examples:

Rspec.configure do |config|
# …
config.use_transactional_examples = true
end

setting this to false gets rid of the nested transaction error, but in both cases I get:

"Validation failed: Email has already been taken, Login has already been taken"

Is this a bug, or a deliberate change, or just something i am doing wrong?

@mooman
mooman commented May 31, 2010

you can nest transactions in PG, it'll just complain and not do anything.

I have the same issue. for me, i think it's the ORM im using (Sequel). seems like transactional support in rspec might just work with AR at the moment.

@wjessop
wjessop commented May 31, 2010

PG does complain about the error, but it does also break per feature transactions.

@mooman
mooman commented May 31, 2010

maybe "Around hooks" for rspec (https://rspec.lighthouseapp.com/projects/16211-cucumber/tickets/605) can help wtih ORM that only does transactions inside a block? in fact, it would be useful for any other general cases where a block is needed too...

@wjessop
wjessop commented Jun 1, 2010

I think this should maybe be an "rspec-1 compat" issue, as these same tests are working fine on rails 2.3.5, rspec 1.3. Unless I'm missing some new configuration option?

@dchelimsky
RSpec member

Is this still a problem on beta.11?

@wjessop
wjessop commented Jun 14, 2010

Still getting the same with .11 and .12 (sorry for the lag, was away for a week)

@hosh
hosh commented Jun 15, 2010

I've been using rspec-rails beta.12 with AR3.beta4, postgresql and I run into these issues I have config.use_transactional_examples true set in my spec_helper, but the examples are clearly not rolling back.

I had run into a similar issue while running rspec-rails beta.7. There were no warnings but the rspec was clearly not running the examples in transactions.

@dchelimsky
RSpec member

What makes you say "clearly not rolling back". There is a cucumber feature that shows this is working as expected, and all rspec is doing is tapping into rails' transaction management. Would you be willing to try to recreate the problem using a rails unit or functional test?

@wjessop
wjessop commented Jun 15, 2010

I can tell it's not rolling back for me because If I create a single user in one of my tests I get a duplicate user validation issue next test. If I take the same tests and run them on a rails 2.3.5/rspec 1.3 app they work just fine so maybe I'm missing some syntax changes?

What do you mean "Would you be willing to try to recreate the problem using a rails unit or functional test?" exactly?

@dchelimsky
RSpec member

I want to find out if this is an rspec problem or a rails problem. If you can create the same test(s) using rails' builtin testing framework and it all works, then we know we have an rspec problem. Otherwise we can push a ticket to rails.

@hosh
hosh commented Jun 16, 2010

On my end, I ended up adding this snippet to my rspec https://gist.github.com/749ee589ccbd278c28b2

Using the before/after to explicitly do the db transactions, I get 6 stores created via Machinist.

Not having the explicit db transaction, I get 27 stores created via Machinist.

I have tried this with both config.use_transactional_examples true and config.use_transactional_examples false and get the same results

@sriedel
sriedel commented Jun 17, 2010

I have seen similar issues with mysql; they only happen occasionally with beta11 but constantly with beta12 (downgrading to beta11 without touching any code reverted to the original behaviour). If this is the same issue, it's either been introduced or aggravated recently.

@sriedel
sriedel commented Jun 17, 2010

A small update: It seems that when a test fails with an sql error (e.g. missing foreign key), the transaction isn't being cleaned up and test data is left in the database. This seems to be a separate issue, so I'll move to a separate ticket.

@dchelimsky
RSpec member

FYI - rspec is not really doing anything here - it just delegates off to active record - if you're using another ORM you should use database cleaner instead.

@dchelimsky
RSpec member

Maybe rspec-rails should just rely on database cleaner instead of AR - thoughts?

@hosh
hosh commented Jun 17, 2010

What is database cleaner, is that a gem?

@dchelimsky
RSpec member

Yes. http://github.com/bmabey/database_cleaner. Cucumber uses it. Very reliable and offers two modes: transaction and truncation. Use transaction for in-memory testing and truncation for in-browser testing (since the app runs in a separate process from the tests).

@dchelimsky
RSpec member

Hey all - I finally got postgres set up, created an app using rails 3 beta 4, rspec rails 2 beta 12 and I can not reproduce this error or problem at all - transactions are rolling back correctly.

I'm closing for now but if someone can provide me with an example app (with all gems vendored) and I can run it and see the failure, I'll reopen.

@hosh
hosh commented Jun 17, 2010

Have you tried running the spec from spec cli instead of rake spec? Since cli spec doesn't do the db purge, the specs run into problems when they depend on a clean database.

@dchelimsky
RSpec member

Rails transaction management (which rspec delegates to) assumes you're starting a run with the database in the condition you want it in.

@hosh
hosh commented Jun 17, 2010

That's fine, but it doesn't clean it up properly at the end of the run, so it starts accumulating records.

@dchelimsky
RSpec member

If every example is running in transactions, there is nothing to clean up.

@hosh
hosh commented Jun 17, 2010

Right, and the problem is that they are not all running in transactions. So every rake spec I run, it keeps adding more and more records.

Anyways, when I have time to pull away from this project for my employers, I'll set something up so you can see it for yourself, maybe narrow down where the problem is. My bet is that either AR or Rspec isn't covering some corner case that comes up when you're using PostgreSQL for a serious app. I've been running into this issue all day this morning and it's getting increasingly annoying.

@wjessop
wjessop commented Jul 6, 2010

OK, I think I've isolated it to an error in the after(:each) block causing the current test's transaction to not get rolled back. I created a demo app here:

http://github.com/wjessop/testfail

The interesting file is tentacle_spec.rb. If you run rake spec directly after cloning and migrating then the first test will fail because of a validation error (expected). However the second test fails because a user already exists in the database, we are still in the same transaction hence the error: WARNING: there is already a transaction in progress.

If you uncomment the begin/rescue stuff in the after(:each) block then the error is trapped and the transactions are handled as expected.

Interestingly if you re-comment the begin/rescue and comment out the Tentacle.create!(@valid_attributes) lines in each test and re-run the specs you get the real error (divided by 0) so a failing test masks an error in the after(:each) block.

This could be considered a regression from 1.2 as these specs worked there, though maybe more aggressive failing of the test suite in this situation would be appropriate?

@dchelimsky
RSpec member

@wjessop - that makes perfect sense! Thank you for tracking this down. I've opened a new issue for this in rspec-core: http://github.com/rspec/rspec-core/issues#issue/60

Cheers,
David

@tispratik

I am seeing this error ("there is no transaction in progress") with rspec-core '2.6.4'. I guess its not fixed yet. Do we need to use database_cleaner with rspec?

@tispratik

Sorry, my bad, i had not cleaned up the old data left over by the previous version of the gem.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.