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
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?
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.
PG does complain about the error, but it does also break per feature transactions.
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...
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?
Is this still a problem on beta.11?
Still getting the same with .11 and .12 (sorry for the lag, was away for a week)
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.
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?
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?
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.
It seems to work OK, was this what you were after (see last commit and comments in the test file: http://github.com/wjessop/Base-Rails-3-project-with-two-tests/blob/264f7330ebc16c4984b9a7472c5b9845efa663c0/test/unit/user_test.rb)?
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
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.
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.
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.
Maybe rspec-rails should just rely on database cleaner instead of AR - thoughts?
What is database cleaner, is that a gem?
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).
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.
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.
Rails transaction management (which rspec delegates to) assumes you're starting a run with the database in the condition you want it in.
That's fine, but it doesn't clean it up properly at the end of the run, so it starts accumulating records.
If every example is running in transactions, there is nothing to clean up.
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.
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:
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?
@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
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?
Sorry, my bad, i had not cleaned up the old data left over by the previous version of the gem.