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.
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).
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