Written by: steve ross on January 25th 2011

You may have used SQLite's in-memory database feature to speed up your tests -- perhaps even utilizing TopFunky's plugin for it. Well... Rails 3 moves a few things around, but no worries. It's still easy to do.

Let's start out by changing database.yml

  
    test:
      adapter: sqlite3
      database: ":memory:"
      verbosity: quiet
  

Simple and to the point. Tells Rails to select the SQLite3 driver for the test environment and store the database in memory. This has the potential to speed up tests immensely.

You'd think everything would be just fine and off we would go, but the lack of a physical database means that we have to force the schema to load before the test run. Here's how.

Create a file in your /config/initializers directory called in_memory_database.rb (or something like that):

  
def in_memory_database?
  Rails.env == "test" and 
    ActiveRecord::Base.connection.class == ActiveRecord::ConnectionAdapters::SQLiteAdapter || 
      ActiveRecord::Base.connection.class == ActiveRecord::ConnectionAdapters::SQLite3Adapter and
    Rails.configuration.database_configuration['test']['database'] == ':memory:'
end

if in_memory_database?
  puts "creating sqlite in memory database"
  load "#{Rails.root}/db/schema.rb"
end
  

This code (trust me, it will look nicer in your text editor than in a Web browser) simply examines the Rails environment to figure out if the environment is the "test" environment. If so, it then checks to figure out if [one of] the SQLite or SQLite3 adapter is being used. If all of the foregoing is true then it looks to find out whether the database has the magic name ':memory:' which denotes an in-memory database.

So if we are using the in-memory database, the initializer code loads the schema into it. End of story.

This post inspired by a blog post by Chris Roos.