Every time I want to run Rake test the task db:test:prepare is being called and it rebuilds my test environment database from schema.rb and migrations. What I would like to achive is to disable the call of db:test:prepare when I want to test make Rails application. Is it possible without modifying Rails gem?
Here's a solution I've seen around:
In your Rakefile:
Rake::TaskManager.class_eval do
def remove_task(task_name)
#tasks.delete(task_name.to_s)
end
end
In lib/tasks/db/test.rake:
Rake.application.remove_task 'db:test:prepare'
namespace :db do
namespace :test do
task :prepare do |t|
# rewrite the task to not do anything you don't want
end
end
end
There is a plugin that takes care of this for you: override_rake_task. Here is a quick usage example:
namespace :db do
namespace :test do
override_task :prepare do; end
end
end
For some older version of rails - you can place Rake::Task['db:test:prepare'].clear at the end of your Rakefile
Related
Defining an existing rake task again appends to the original, but I'd like to prepend to the db:migrate task. I want to raise an error beforehand in some cases. Is there a good way to prepend to an existing rake task?
Try adding a db:custom task on 'db' namespace and invoke db:migrate with enhance method
# add your custom code on db:custom
namespace 'db' do
task 'custom' do
puts "do custom db stuff"
end
end
# invoke db:migrate
Rake::Task['db:migrate'].enhance [:custom]
Might be better to define your own task and call db:migrate inside.
namespace :custom_db do
desc 'migrate db if condition true'
task :migrate do
if true #your condition
Rake::Task['db:migrate'].invoke
else
#process errors
end
end
end
I have a bunch of tests that aren't unit or functional tests, they're of the format test/foo/special_test.rb
I want to create a rake task like rake test:units that will run all the tests in the foo folder. How do I do this?
Edit: I'd actually like rake test:foo to be a little different from rake test:units, in that I do not want it to run when I do simply rake test.
I don't remember where this is from, so unfortunately I can't give proper acknowledgement, but this should work. I say "should" because I've stopped using it, but grabbed it from my git history.
# First, 'reopen' the default :test namespace and create your custom task.
namespace :test do
Rake::TestTask.new(:foo_tests => ["test:prepare", "other_dependent_rake_tasks"] ) do |t|
DatabaseCleaner.strategy = :transaction # If using this.
t.libs << "test"
# Will also get subfolders within test/foo
t.test_files = FileList['test/foo/**/*_test.rb', 'test/foo/*_test.rb']
end
end
You can remove the default "test" task and redefine it so that when you run rake test it will automatically also run rake test:foo_tests.
remove_task "test"
desc 'Adding onto Rails regular tests'
task :test do
# Add all the names of tests you want run here.
errors = %w(test:units test:functionals test:integration test:foo_tests).collect do |task|
begin
puts "Running: #{task}"
Rake::Task[task].invoke
nil
rescue => e
task
end
end.compact
abort "Errors running #{errors * ', '}!" if errors.any?
end
I have many rake scripts named example1_task, example1_task2 ... etc. I like to convert this scripts into once and use example1:task1, example1:task2 like i do with the command rake db:migrate on rails migrations.
Any idea ?
Thanks in advance.
Yes, use namespace:
namespace "example" do
task :task1 do
#some code
end
task :task2 do
#some code
end
end
I have a Rails 2.2 project in which I want to override the functionality of the rake db:test:prepare task. I thought this would work, but it doesn't:
#lib/tasks/db.rake
namespace :db do
namespace :test do
desc "Overridden version of rails' standard db:test:prepare task since the schema dump used in that can't handle DB enums"
task :prepare => [:environment] do
puts "doing db:structure:dump"
Rake::Task['db:structure:dump'].invoke
puts "doing db:test:clone_structure"
Rake::Task['db:test:clone_structure'].invoke
end
end
end
I get the standard task's behaviour. If I change the name of the task to :prepare2 and then do rake db:test:prepare2, then it works fine. The natural conclusion I draw from this is that my rake tasks are being defined before the built-in Rails ones, so mine is overridden by the standard :prepare task.
Can anyone see how I can fix this? I'd rather override it than have to use a new task. Thanks, max
If you define a rake task that already exists, its execution gets appended to the original task's execution; both tasks will be executed.
If you want to redefine a task you need to clear the original task first:
Rake::Task["db:test:prepare"].clear
It's also useful to note that once a task has been executed in rake, it won't execute again even if you call it again. This is by design but you can call .reset on a task to allow it to be run again.
You have to remove the default task before adding your own:
Rake.application.instance_variable_get('#tasks').delete('db:test:prepare')
namespace 'db' do
namespace 'test' do
task 'prepare' do
# ...
end
end
end
A fairly popular idiom is to create a convenience method called remove_task like so:
Rake::TaskManager.class_eval do
def remove_task(task_name)
#tasks.delete(task_name.to_s)
end
end
def remove_task(task_name)
Rake.application.remove_task(task_name)
end
(Source: drnic/newgem)
Create a new project.rake file at lib/tasks/, and paster below code into it.
namespace :mv do
desc "Display hint and info for your rails 4 project"
task info: :environment do
puts 'Run rake test to test'
end
end
task(:default).clear.enhance ['mv:info']
inspired by Krasimir Angelov's blog
I'm attempting to use the new standard way of loading seed data in Rails 2.3.4+, the db:seed rake task.
I'm loading constant data, which is required for my application to really function correctly.
What's the best way to get the db:seed task to run before the tests, so the data is pre-populated?
The db:seed rake task primarily just loads the db/seeds.rb script. Therefore just execute that file to load the data.
load "#{Rails.root}/db/seeds.rb"
# or
Rails.application.load_seed
Where to place that depends on what testing framework you are using and whether you want it to be loaded before every test or just once at the beginning. You could put it in a setup call or in a test_helper.rb file.
I'd say it should be
namespace :db do
namespace :test do
task :prepare => :environment do
Rake::Task["db:seed"].invoke
end
end
end
Because db:test:load is not executed if you have config.active_record.schema_format = :sql (db:test:clone_structure is)
Putting something like this in lib/tasks/test_seed.rake should invoke the seed task after db:test:load:
namespace :db do
namespace :test do
task :load => :environment do
Rake::Task["db:seed"].invoke
end
end
end
I believe Steve's comment above should be the correct answer. You can use Rails.application.load_seed to load seed data into your test envoironment. However, when and how often this data is loaded depends on a few things:
Using Minitest
There is no convenient way to run this file once before all tests (see this Github issue). You'll need to load the data once before each test, likely in the setup method of your test files:
# test/models/my_model_test.rb
class LevelTest < ActiveSupport::TestCase
def setup
Rails.application.load_seed
end
# tests here...
end
Using RSpec
Use RSpec's before(:all) method to load seed data for all test for this model:
describe MyModel do
before(:all) do
Rails.application.load_seed
end
describe "my model..." do
# your tests here
end
Hope this helps.
Building on Matt's answer, if taking that sort of route, I recommend calling Rails.application.load_seed in a before(:suite) block in rspec_helper.rb rather than in a before(:all) block in any file. That way the seeding code is invoked only once for the entire test suite rather than once for each group of tests.
rspec_helper.rb:
RSpec.configure do |config|
...
config.before(:suite) do
Rails.application.load_seed
end
...
end
We're invoking db:seed as a part of db:test:prepare, with:
Rake::Task["db:seed"].invoke
That way, the seed data is loaded once for the entire test run, and not once per test class.
Adding Rake::Task["db:seed"].invoke to the db:test:prepare rake task did not work for me. If I prepared the database with rake db:test:prepare, and then entered the console within the test environment, all my seeds were there. However, the seeds did not persist between my tests.
Adding load "#{Rails.root}/db/seeds.rb" to my setup method worked fine, though.
I would love to get these seeds to load automatically and persist, but I haven't found a way to do that yet!
For those using seedbank, it changes how seeds are loaded, so you probably can't/don't want to use the load ... solution provided here.
And just putting Rake::Task['db:seed'].invoke into test_helper resulted in:
Don't know how to build task 'db:seed' (RuntimeError)
But when we added load_tasks before that, it worked:
MyApp::Application.load_tasks
Rake::Task['db:seed'].invoke