I have a very simple Rakefile to test a small Ruby gem. It looks like this:
Rake::TestTask.new
task :default => :test
It invokes two tests that define constants with the same name. This results in errors being output by the second test like this:
warning: already initialized constant xxxxx
The reason for this is because Rake executes all of the tests within a single Ruby instance:
/usr/bin/ruby -I"lib" -I"/usr/lib/ruby/gems/2.1.0/gems/rake-10.3.2/lib" "/usr/lib/ruby/gems/2.1.0/gems/rake-10.3.2/lib/rake/rake_test_loader.rb" "test/test*.rb"
How should I specify that each test should be run in a separate Ruby instance ?
I have achieved this as shown below but I wonder if there is a better way because this solution doesn't scale well for lots of tests.
Rake::TestTask.new(:one) { |t| t.test_files = %w(test/test_one.rb) }
Rake::TestTask.new(:two) { |t| t.test_files = %w(test/test_two.rb) }
task :default => [:one, :two]
Instead of using Rake::TestTask, you could define a test task in your Rakefile that loops through each test file and runs them with sh like this:
task :test do
libs = ['lib',
'/usr/lib/ruby/gems/2.1.0/gems/rake-10.3.2/lib',
'/usr/lib/ruby/gems/2.1.0/gems/rake-10.3.2/lib/rake/rake_test_loader.rb']
test_files = FileList['test/**/test*.rb']
test_files.each do |test_file|
includes = libs.map { |l| "-I#{l}"}.join ' '
sh "ruby #{includes} #{test_file}"
end
end
Related
We have developed few test cases using mini-test / ruby
Now we are trying to run it using rake files.
its working fine if we are running below code.
require 'rake'
require 'rake/testtask'
Rake::TestTask.new do |t|
t.test_files = FileList['../Home/*TC1.rb']
t.verbose = true
end
But we are putting the above code in separate task then id does not run the test
task :myCustom_task do
Rake::TestTask.new do |t|
t.test_files = FileList['../Home/*TC1.rb']
t.verbose = true
end
end
Then we run it by below command
rake myCustom_task
and it does not run the test.Also it does not show any error while running with --trace option.
What is missing in this approach ?
I have a file containing a class of multiple tests (using minitest). I have require 'minitest/autorun' at the top of the file and all tests run correctly when I call the file directly (ruby my_tests.rb).
So far, so good. However, now I'm trying to run my tests via rake.
require "rake/testtask"
task :default => [:test]
Rake::TestTask.new do |t|
t.libs << Dir.pwd + "/lib/examples"
t.test_files = FileList['test/test*.rb']
end
Calling rake shows test/my_test.rb getting called but no tests within the class get run (0 tests, 0 assertions, etc.). I do get these warnings:
...gems/minitest-5.8.0/lib/minitest/assertions.rb:17: warning: already initialized constant MiniTest::Assertions::UNDEFINED
...ruby/2.1.0/lib/ruby/2.1.0/minitest/unit.rb:80: warning: previous definition of UNDEFINED was here
How can I run my tests within rake successfully? I am not using rails.
EDIT: Here is the top of my test file:
require 'minitest/spec'
require 'minitest/autorun'
require 'minitest/reporters'
reporter_options = { color: true }
Minitest::Reporters.use![Minitest::Reporters::DefaultReporter.new(reporter_options)]
class Test_PowerSpecInputs < Minitest::Test
def setup
#mc = TestClass.new()
end
def test_does_lib_have_constant
# my test code
end
end
Try changing your Rakefile to this.
require "bundler/gem_tasks"
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList['test/**/*_test.rb']
end
task :default => :test
jphager2 got me thinking about tool versions and it turned out that my version of rake was fairly old. Updating to 11.x did the trick.
I'm attempting to capture the equivalent of rake -D programmatically. I can load the Rakefile I'm targeting and see a list of tasks, but I can not figure out how to get the descriptions.
This will let me see the tasks that I am interested in:
Dir.chdir #myTarget
rake = Rake::Application.new
Rake.application = rake
rake.init
rake.load_rakefile
tasks = Rake.application.tasks
puts tasks.inspect
The above outputs something similar to:
[<Rake::Task default => [test]>, <Rake::Task foodcritic => []>, <Rake::Task integration => [kitchen:all]>]
My question is how to access the desc comments that are visible if I run rake -D. Here's what I'm after:
rake foodcritic
Run Foodcritic lint checks
rake integration
Alias for kitchen:all
rake kitchen:all
Run all test instances
Here's the final solution. The key was that I was missing metadata from the taskmanager:
Dir.chdir #myTarget
rake = Rake::Application.new
Rake::TaskManager.record_task_metadata = true
Rake.application = rake
rake.init
rake.load_rakefile
Rake.application.tasks.each do |t, n|
puts t
puts t.full_comment
puts "\n"
end
Use the methods comment or full_comment for that. More docs on the Rake::Task class here.
How do I initialize an RSpec Rake task using RSpec::Core::RakeTask?
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new do |t|
# what do I put in here?
end
The Initialize function documented at
http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method isn't very well-documented; it just says:
- (RakeTask) initialize(*args, &task_block)
A new instance of RakeTask
What should I put for *args and &task_block?
I'm following in the footsteps of someone who had already started to build some ruby automation for a PHP project using RSpec in combination with Rake. I'm used to using RSpec without Rake, so I'm unfamiliar with the syntax.
Thanks,
-Kevin
Here is an example of my Rakefile:
require 'rspec/core/rake_task'
task :default => [:spec]
desc "Run the specs."
RSpec::Core::RakeTask.new do |t|
t.pattern = "spec.rb"
end
desc "Run the specs whenever a relevant file changes."
task :watch do
system "watchr watch.rb"
end
This allows to run specs defined in the spec.rb file from Rake
This is what my rakefile looks like
gem 'rspec', '~>3'
require 'rspec/core/rake_task'
task :default => :spec
desc "run tests for this app"
RSpec::Core::RakeTask.new do |task|
test_dir = Rake.application.original_dir
task.pattern = "#{test_dir}/*_spec.rb"
task.rspec_opts = [ "-I#{test_dir}", "-I#{test_dir}/source", '-f documentation', '-r ./rspec_config']
task.verbose = false
end
You can 'rake' from your tests directory and it will run all tests with a name [something]_spec.rb - and it should work across different test directories (e.g. different projects); if you have source in a separate directory (e.g. in the code above, a subdirectory called '/source' it will pick them up. Obviously, you can change that source directory to what you want.
Here's the rspec_config file I use - you can add your own settings in here:
RSpec.configure do |c|
c.fail_fast = true
c.color = true
end
I have a few pure-JavaScript, client-side tests using PhantomJS. These I'd like to integrate with rake test.
Currently I use this:
namespace :test do
task :client do
basedir = Rails.root.join("test", "client")
sh "cd #{basedir} && phantomjs lib/run-qunit.js index.html"
end
end
task :test => "test:client"
However, this integration is far from perfect; if one of these tests fails, rake aborts. Also, in contrast to :units, :functionals and :integration, there is no summary of the issues at the end (e.g. "6 tests, 21 assertions, 1 failures, 0 errors").
I could extract that data easily enough, but how do I tell Rake to add it to the total test tally?
You are calling via sh a shell command. Ruby does not know, that it is a test.
In addition sh seems to stop, if a failure occurs.
You have to do two things: Catch the error and check the result of your call.
An example:
require 'rake'
$summary = Hash.new(0)
def mytest(name, cmd)
$summary['test'] += 1
sh cmd do |ok, res|
if ok
$summary['ok'] += 1
else
$summary['failure'] += 1
puts "#{cmd } failed"
end
end
end
namespace :test do
task :one do |tsk|
mytest(tsk.name, "dir")
end
task :two do |tsk|
mytest(tsk.name, "undefined_cmd")
end
task :summary do
p $summary
end
end
task :test => "test:one"
task :test => "test:two"
task :test => "test:summary"
shis called with a block to catch failures. Inside the block, I analyse the result (true for ok, false if the script stops with an error. The result is added to a summary hash.
For your use, you may adapt the code and split the code into two files: All test in one file. And the rake file get a Rake::TestTast.
Your test file may look like this:
gem 'test-unit'
require 'test/unit'
class MyTest < Test::Unit::TestCase
def test_one
assert_nothing_raised{
basedir = Rails.root.join("test", "client")
res = system("cd #{basedir} && phantomjs lib/run-qunit.js index.html")
assert_true(res)
}
end
def test_two
assert_nothing_raised{
res = `dir` #Test with windows
assert_match(/C:/, res) #We are in c:
}
end
end
This works only, if your test finish with a exit code. Perhaps you can use `` instead and get the output of your test for a detailed analyze.