rake test without running re-creating database?

Mark napisał(a):

Hi,

Complexly new to rails testing and having a few problems.

Please correct me if I have any of this wrong:
When I run rake test this first re-cerate's my test database, however
because I am using a data type that is unsupported by rails, rake is
aborted.

Is there a way to run the tests without recreating the database?

Better solution would be to change schema format to 'sql' in config/
environment.rb:

  config.active_record.schema_format = :sql

then the database-native-dump will be used to recreate the test
database.

Of course, you can make rake to not recreate the database, but I don't
remember how. :wink:
Look for the rake tasks sources in
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/tasks/testing.rake and
databases.rake
(change version numbers when necessary).

Jean Nibee wrote:

My Migration shows example with 'tinyint', which is not a valid symbol
(data type) in Rails.

>>>>>>>>>> migration
create_table :testing do |t|
  t.column :last_updated, :timestamp, :null => false
  t.column :info, 'tinyint(2) not null', :default => 0
end

[...]

> desc testing;
+--------------+------------+------+-----+---------+----------------+
> Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+---------+----------------+
> id | int(11) | NO | PRI | NULL | auto_increment |
> last_updated | datetime | NO | | | |
> info | tinyint(2) | NO | | 0 | |
+--------------+------------+------+-----+---------+----------------+

AFAIK test-database recreation does not use migrations, but database
dump, so if you use database-specific types or constructs (triggers,
for example) you should use :sql dump type, as the default tries to
express the database structure using rails syntax. You can look in
the ./db/ directory and examine files found there (after `rake test`)
to see how the dump looks like.
What is the 'desc testing' output if you do it in the test database
after rake db:test:prepare ?

By the way, currently 'create_table t.column' allows database-native
types, but there are problems when you use it in 'add_column'. I saw
it fixed in SVN, though.

I found a post (http://snippets.dzone.com/posts/show/2031) about how to make tests use migrations rather than dumping the dev database. I find this has more integrity as that is how a real production environment would be created. It also tests the migrations which is a good thing. I can imagine also having tests that migrate to a specific point then create data, then migrate further to test updates of the schema.

Here is the code from that post which I put at the end of my rake file:

module Rake
   module TaskManager
     def redefine_task(task_class, args, &block)
       task_name, deps = resolve_args(args)
       task_name = task_class.scope_name(@scope, task_name)
       deps = [deps] unless deps.respond_to?(:to_ary)
       deps = deps.collect {|d| d.to_s }
       task = @tasks[task_name.to_s] = task_class.new(task_name, self)
       task.application = self
       task.add_comment(@last_comment)
       @last_comment = nil
       task.enhance(deps, &block)
       task
     end
   end
   class Task
     class << self
       def redefine_task(args, &block)
         Rake.application.redefine_task(self, args, &block)
       end
     end
   end
end

def redefine_task(args, &block)
   Rake::Task.redefine_task(args, &block)
end
namespace :db do
   namespace :test do

     desc 'Prepare the test database and migrate schema'
     redefine_task :prepare => :environment do
       if defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
         #Rake::Task[{ :sql => "db:test:clone_structure", :ruby => "db:test:clone", :migration => "db:test:migrate" }[ActiveRecord::Base.schema_format]].invoke
         Rake::Task["db:test:migrate"].invoke
       end
     end

     desc 'Use the migrations to create the test database'
     task :migrate => 'db:test:purge' do
       begin
         ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['development'])
         schema_version = ActiveRecord::Base.count_by_sql("SELECT version AS count_all FROM schema_info LIMIT 1;")
         ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
         ActiveRecord::Migrator.migrate("db/migrate/", schema_version)
       rescue
         puts "The development database doesn't exist or no migrations have been run on it."
       end
     end

   end
end

Michael