7
votes

Where does Rails store data created by saving activerecord objects during tests?

I thought I knew the answer to that question: obviously in the _test database. But it looks like this is not true!

I used this system to test what's happening to saved ActiveRecord data during rspec tests:

$ rails -d mysql test

$ cd test

$ nano config/database.yml ...

... create mysql databases test_test, test_development, test_production

$ script/generate rspec

$ script/generate rspec_model foo

edit Foo migration:

class CreateFoos 

$ rake db:migrate

edit spec/models/foo_spec.rb:

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe Foo do
  before(:each) do
    @valid_attributes = {
      :bar => 12345
    }
  end

  it "should create a new instance given valid attributes" do
    foo = Foo.new(@valid_attributes)
    foo.save
    puts "sleeping..."
    sleep(20)
  end
end

$ rake spec

When you see "sleeping...", change to another open terminal with a mysql session conneted to the test_test database and do:

mysql> select * from foos; Empty set (0.00 sec)

Why doesn't the mysql session show any records in the test_test database while the test is running?

3

3 Answers

14
votes

Items in the test database are erased by default after each test is run, by design. This is done to make sure that each of your tests has its own sandbox to play in that doesn't cause any interactions with the tests before it.

Again, this is by design. You don't want tests that are manipulating the same set of data (or rely on synchronous execution), because there is no guarantee of execution order.

However, I believe if you modify you test/test_helper.rb file to say this:

self.use_transactional_fixtures = false

instead of

self.use_transactional_fixtures = true

It will cause the data in your test database to persist.

ALSO: My advice is specifically designed to work with Test::Unit, not RSpec. However, I imagine that there is a similar setting your spec_helper.rb you should be looking for.

4
votes

You can observe records being added to the test database with:

tail -f log/test.log

You should see the transactions flying by as the tests are run.

4
votes

"But why does the mysql query show no data in the database while the test is running?"

Because it's in a transaction. If you turn transactional fixtures off your tests will run much slower than before.