views:

88

answers:

2

UPDATE: FIXED!!!!! As I suspected it was a config that was messed up somehow - much hair pulling ensued. For some reason "require 'test_help'" was deleted from test_helper.rb, added it back in and all the tests are in a transaction now.

This smells like a basic config issue but I can't figure out what. Rails 2.3.5, Ruby 1.8.7 patch 173. I am using Shoulda+factory girl and have a test for that creates a couple of users for setup

class UserTest < ActiveSupport::TestCase 
  use_transactional_fixtures = true
  context "getting a user's email" do 
    setup do
      ... stubs ...
    end

    should "populate email field if not present" do
      @user = Factory.create(:molly_perkins)
      @user.get_email(@facebook_session) 
      assert_equal '[email protected]', @user.email
    end

    should "not populate email if already present" do
      @user = Factory.create(:amanda_levy)
      @user.get_email(@facebook_session)
      assert_equal '[email protected]', @user.email
    end
  end
end 

The tests pass, but problem is these don't seem to be cleared after running - looking at test.log, I see that the transactions commit the inserts! What gives?

  # First test
  User Create (0.3ms)   INSERT INTO `users` ...
  SQL (0.4ms)   COMMIT
  # Second test
  SQL (0.1ms)   BEGIN
  User Create (0.3ms)   INSERT INTO `users` ....
  SQL (0.4ms)   COMMIT
  SQL (0.1ms)   BEGIN
  User Update (0.4ms)   UPDATE `users` ....
  SQL (0.4ms)   COMMIT

To work around this I'm just using a teardown block of "Model.all.each(&:destroy)", but I shouldn't have to do that, and it's slow/janky to have to destroy everything I instantiate. The transactions should just rollback...

Table in the test DB is InnoDB:

mysql> select engine from tables where table_name = 'users' and table_schema = 'voltron_test';
+--------+
| engine |
+--------+
| InnoDB |
+--------+

and I'm using transactional fixtures (from test_helper.rb):

class ActiveSupport::TestCase
  use_transactional_fixtures = true
end

Transactions do work (accessing test DB from console):

mysql> select * from users;
Empty set (0.00 sec)
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `users` ...
Query OK, 1 row affected (0.00 sec)
mysql> select * from users;
   ...
1 row in set (0.00 sec)
mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from users;
Empty set (0.00 sec)
A: 

If you are using MyISAM db engine, this is pretty normal, as it doesn't support transactions.

mdrozdziel
whoops, sorry I forgot they're innoDB tables, updated my q
ambertch
+1  A: 

I've never used the use_transaction_fixtures = true in the test case, but have alwsays had:

class Test::Unit::TestCase
    ....
    self.use_transactional_fixtures = true
    ....
end

in the test/test_helper.rb file that comes with Rails, and never had that problem.

stephenr
thanks Stephen. Yeah I've got transactional_fixtures configured (and updated my Q with that info)
ambertch
weird. two thoughts: tests aren't executed in the order you specify them, so could it being set to false in another test which is being executed first? The other thing is can you prove that the mysql server will actually rollback a transaction?
stephenr
Stephen, I found I didn't have "require 'test_help'" in test_helper for whatever reason. Thanks for responding and getting my brain working, I marked your answer as the correct one so you can get the bounty :)
ambertch