How do you write a task to run tests in Rails 3? - ruby-on-rails

I would like to write rake tasks to customize tests. For example, to run unit tests, I created a file with the following code and saved it as lib/tasks/test.rake:
task :do_unit_tests do
cd #{Rails.root}
rake test:units
end
Running rake do_unit_tests throws an error: can't convert Hash into String.
Working in Rails 3.0.7 and using built-in unit test framework.
Thanks.

There is no need to cd. You can simply...
task :do_unit_tests do
Rake::Task['test:units'].invoke
end
But if you really want to cd, that's how you call shell instructions:
task :do_unit_tests do
sh "cd #{Rails.root}"
Rake::Task['test:units'].invoke
end
Well, in fact there is a shorter version. The cd instruction have a special alias as Chris mentioned in the other answer, so you can just...
task :do_unit_tests do
cd Rails.root
Rake::Task['test:units'].invoke
end
If you want to go further, I recommend Jason Seifer's Rake Tutorial and Martin Fowler's Using the Rake Build Language articles. Both are great.

You're trying to interpolate a value that's not in a string, and you're also treating rake test:units like it were a method call with arguments, which it's not.
Change the cd line so you're calling the method with the value of Rails.root, and change the second line to be a shell instruction.
task :do_unit_tests do
cd Rails.root
`rake test:units`
end

Related

Run two ruby scripts from rake task

So this is a simple rake task:
task :map_reduce do
puts 'Running map reduce scripts...'
ruby "#{PADRINO_ROOT}/map_reduce/raw_visits_map.rb '03-08-2016' 90" && ruby "#{PADRINO_ROOT}/map_reduce/raw_visits_reducer.rb"
end
The first script outputs the result in STDOUT to be further read by the so called 'reducer'.
In the terminal, I am able to run those two scripts like:
ruby first_script.rb param1 param2 | ruby second_script.rb
So the second script can read from STDOUT like
res = ARGF
But how can I line up the 2 executions inside that rake task?
How I wrongfully tried it's not working.
It might be easier to require the ruby class directly into your rake task, but if you want to run a script from a rake task you can run any shell code in Ruby using backticks, like this:
`ruby first_script.rb param1 param2 | ruby second_script.rb`
Perhaps you should use backticks or the %x syntax.
Also see answers to: Ruby, Difference between exec, system and %x() or Backticks

How can i add a task that will run after rake test:db:prepare in Rails

I am using rails 4.2 and i am trying to run test using the command rake test.I am trying to use plv8 extention so i create it manually from psql console, then when i run the test it seems like it has deleted that extension from postgres. I looked into rails 4.2 project and i noticed that they brought test:db:prepare back. This is what is deleting the plv8 extension every time. how can i add a pice of code that will run after the test:db:prepare or test:db:create?
I am not a big fan of modifying Rakefile solution.
You can name multiple tasks inline:
rake test:db:create test:db:prepare custom:task
Or when you create a new rake task you can make it dependent on any other task:
desc "the dependent task will run before this one"
task my_task: :other_task do
# stuff
end
You can also arbitrarily invoke other tasks:
Rake::Task['db:test:prepare'].invoke
More info here: http://jasonseifer.com/2010/04/06/rake-tutorial and here: How to run Rake tasks from within Rake tasks?

How to write and execute an individual rake task outside the Rails application folder

How do you write a rake task outside the Rails application directory and make it run.
For example, say write a sample rake task
task :dummy do
puts User.first.first_name
end
this task is under ~/fun/sample.rake
And my rails application is located at ~/my_app/
Now I need to run the sample.rake. I know i need to load the environment, DB etc., etc., how do i do that? Stuck at this for the past hour.
I tried the one below, obviously it did not work because it did not know how to build it.
rake -f ~/my_app/Rakefile dummy
Note: I should not touch the files inside the Rails application but I can write whatever I want inside the fun directory
You need to create a Rakefile and load the rake gem. See this answer: Ruby: Accessing rake task from a gem without Rails

How do I find the source file for a rake task?

I know you can view all possible rake tasks by typing
rake -T
But I need to know what exactly a task does. From the output, how can I find a source file that actually has the task? For example, I'm trying to find the source for the db:schema:dump task.
I know this is an old question, but in any case:
rake -W
This was introduced in rake 0.9.0.
http://rake.rubyforge.org/doc/release_notes/rake-0_9_0_rdoc.html
Support for the –where (-W) flag for showing where a task is defined.
Despite what others have said, you can programmatically get the source location of rake tasks in a rails application. To do this, just run something like the following in your code or from a console:
# load all the tasks associated with the rails app
Rails.application.load_tasks
# get the source locations of actions called by a task
task_name = 'db:schema:load' # fully scoped task name
Rake.application[task_name].actions.map(&:source_location)
This will return the source locations of any code that gets executed for this task. You can also use #prerequisites instead of #source_location to get a list of prerequisite task names (e.g. 'environment', etc).
You can also list all tasks loaded using:
Rake.application.tasks
UPDATE: See Magne's good answer below. For versions of rake >= 0.9.0 you can use rake -W to show the source location of your rake tasks.
There is no programmatic way to do this unfortunately. Rake tasks can be loaded either from rails itself, lib/tasks, or from any plugin with a tasks directory.
This should nab most everything not within Rails itself:
find . -name "*.rake" | xargs grep "whatever"
As for db:schema:dump, here's the source:
desc "Create a db/schema.rb file that can be portably used against any DB supported by AR"
task :dump => :environment do
require 'active_record/schema_dumper'
File.open(ENV['SCHEMA'] || "#{RAILS_ROOT}/db/schema.rb", "w") do |file|
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
end
end
It can be found on line 242 of lib/tasks/database.rake in the rails 2.2.2 gem. If you've got a different version of Rails, just search for "namespace :schema".
You probably actually want the source of the ActiveRecord::SchemaDumper, but I think you should have no trouble figuring out where that is. :-)
For most rake tasks in Rails, look in the Rails gem directory, in lib/tasks.
If you've vendored Rails into your app directory structure then look in vendor/rails/railties/lib/tasks instead
Either way, db:schema:dump is in databases.rake.

How to run a single test from a Rails test suite?

How can I run a single test from a Rails test suite?
rake test ANYTHING seems to not help.
NOTE: This doesn't run the test via rake. So any code you have in Rakefile will NOT get executed.
To run a single test, use the following command from your rails project's main directory:
ruby -I test test/unit/my_model_test.rb -n test_name
This runs a single test named "name", defined in the MyModelTest class in the specified file. The test_name is formed by taking the test name, prepending it with the word "test", then separating the words with underscores. For example:
class MyModelTest < ActiveSupport::TestCase
test 'valid with good attributes' do
# do whatever you do
end
test 'invalid with bad attributes' do
# do whatever you do
end
end
You can run both tests via:
ruby -I test test/unit/my_model_test.rb
and just the second test via
ruby -I test test/unit/my_model_test.rb -n test_invalid_with_bad_attributes
Run a test file:
rake test TEST=tests/functional/accounts_test.rb
Run a single test in a test file:
rake test TEST=tests/functional/accounts_test.rb TESTOPTS="-n /paid accounts/"
(From #Puhlze 's comment.)
For rails 5:
rails test test/models/my_model.rb
Thanks to #James, the answer seems to be:
rails test test/models/my_model.rb:22
Assuming 22 is the line number of the given test. According to rails help:
$ rails test --help
You can run a single test by appending a line number to a filename:
bin/rails test test/models/user_test.rb:27
Also, please note that your test should inherit from ActionDispatch::IntegrationTest for this to work (That was my mistake):
class NexApiTest < ActionDispatch::IntegrationTest
.
.
.
Rails 5
I used this way to run single test file (all the tests in one file)
rails test -n /TopicsControllerTest/ -v
Another option is to use the line number (which is printed below a failing test):
rails test test/model/my_model.rb:15
In my situation for rake only works TESTOPTS="-n='/your_test_name/'":
bundle exec rake test TEST=test/system/example_test.rb TESTOPTS="-n='/your_test_name/'"
To run a single test in the actual Rails suite:
bundle exec ruby -I"railties/test" actionpack/test/template/form_options_helper_test.rb
That was a silly midnight question of mine. Rails kindly prints the command it is executing upon rake test. The rest is a cut and paste exercise.
~/projects/rails/actionpack (my2.3.4)$ ruby -I"lib:test" "/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/controller/base_test.rb"
The best way is to look directly into the guides: http://guides.rubyonrails.org/contributing_to_ruby_on_rails.html#running-tests
cd actionmailer
bundle exec ruby -w -Itest test/mail_layout_test.rb -n test_explicit_class_layout
If you want to run a single test, you can just run them as a regular Ruby script
ruby actionmailer/test/mail_layout_test.rb
You can also run a whole suite (eg. ActiveRecord or ActionMailer) by cd-ing into the directory and running rake test inside there.
To re-run a test that just failed, copy-n-paste the failed test name into
rails test -n [test-name]
EXAMPLE
When your test suite reports this:
> rails test
...
Error:
PlayersControllerTest#test_should_show_player:
ActionView::Template::Error: no implicit conversion from nil to integer
you rerun the failing test with this:
rails test -n PlayersControllerTest#test_should_show_player
If rake is running MiniTest, the option is --name instead of -n.
rake test TEST=test/unit/progress_test.rb TESTOPTS="--name=testCreate"
First, access the folder of the lib you want to test(this is important) and then run:
~/Projects/rails/actionview (master)$ ruby -I test test/template/number_helper_test.rb
Rails folder
bundle install
bundle exec ruby -I"activerecord/test" activerecord/test/cases/relation/where_test.rb
Note you need to load appropriate folder: "activerecord/test" (where you have test)

Resources