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?
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).
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).
I would be more concerned that you can’t create that special data type
then ‘hacking’ the way Rake handles the DB migrations.
Just use a string for the database specific sql you want used in place
of the symbols on the method you’re executing in your migration.
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
jbateman@the-necropolis:~/sandbox/shinny/trunk$ rake db:migrate
(in /home/jbateman/sandbox/shinny/trunk)
Using AdapterExtensions
== CreateTesting: migrating
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
[…]
mysql> 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
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.
Where are you using this data type?
I don’t know if a non-primitive data type will interact correctly inside
a
fixture, but you should at least be able to put this in the top of your
fixture:
<% require ‘my_esoteric_type’ %>
fix1:
id: 2
data: etc.
Is there a way to run the tests without recreating the database?
Yes. Use rake test --trace --dry-run, find the name of the low-level
task
that calls the actual tests, and invoke that on a command line instead
of
test.
Tip: You want to use fixtures in your tests. You need them now, and you
need
them later. Trust me! Work a little, now, to fix them with this data
type.