Running minitest handler tests inside another ruby script - ruby

I'd like to run my minitest handler tests inside another ruby script (a bootstrapper script of sorts). I'd like to return the results of my tests to a variable that I can then parse to make sure everything passed before moving on. Is this possible? If so, what does the syntax for something like this look like?

You can shell out to run the test and capture the output.
puts "Running foo test:"
output = `ruby -Ilib:test test/test_foo.rb`
puts output
puts "Completed foo test."

Okay so I figured out how to do this using the rake::test library. This code will execute a minitest test, then slurp in the xml from the report and determine if everything passed or not.
require 'rake'
require 'rake/testtask'
require 'ci/reporter/rake/minitest'
require 'xmlsimple'
Rake::TestTask.new do |t|
t.verbose = true
t.test_files = FileList['system_tests/vm_tests.rb']
end
task :test => :"ci:setup:minitest"
Rake::Task[:test].execute
results = XmlSimple.xml_in('test/reports/TEST-VMtests.xml')
if results["failures"] > 0 or results["errors"] > 0
raise "The VM Tests have resulted in failures or errors"
end

Related

Is there any way to run Rspec tests on a single Ruby file?

I would like to run some tests on some code kata exercises that I am working on. Is it possible to run Rspec tests on a single Ruby file? I tried adding require 'rspec' to the top of the file and then the command rsepc from the project dir but the following is returned:
F
Failures:
1) Sentence reverser reverses the words in a sentence
Failure/Error: expect(sentence_reverser(test_sentence)).to eq('I am backwards')
NoMethodError:
undefined method `sentence_reverser' for #<RSpec::ExampleGroups::SentenceReverser:0x0000559764dc5950>
The code I have is:
require 'rspec'
def sentence_reverser str
str.split.reverse.join(' ')
end
describe "Sentence reverser" do
it 'reverses the words in a sentence' do
test_sentence = "backwards am I"
expect(sentence_reverser(test_sentence)).to eq('I am backwards')
end
end
Try running rspec </path/to/kata.rb>. You shouldn't even require 'rspec' then - just tested your example.

Why undefined method `expect' when checking in at_exit hook

I am trying to check the exitstatus of a command through the below code. It is resulting in an error --->undefined method 'expect'
require 'rspec'
require 'rspec/expectations'
at_exit do
\`cat /etc/redhat-release\`
expect($?.exitstatus).to eq(0)
end
Can any one please help me in solving this problem
Your code is suppose be a test case based on rspec, and you are mixing it with normal ruby code.
In order to test your code with rspec you need to wrap the test scenarios and cases inside a describe and it block, only then you'll have access to the expect method, like so:
# test.rb
require 'rspec'
require 'rspec/expectations'
describe 'Test exit status' do
it "check status" do
`cat /etc/redhat-release`
expect($?.exitstatus).to eq(0)
end
end
and you run this code with rspec command line, like: rspec test.rb
The code you had before, was using the at_exit block. This is only called when you exit the program, or receive a signal for it to be killed.

Testing rake tasks with rspec doesn't seem to work

I'm trying to test a very simple rake task with rspec, but I'm finding it very difficult and whatever change I do my tests don't seem to fail...
This is the task I'm trying to test:
desc 'Outputs the current version of Rivendell'
task version: :environment do
puts Rivendell::VERSION
end
As you can see, it's a very basic task.
This is my test:
describe 'Rakefile' do
before :each do
Rake.application.rake_require File.expand_path(
'../../Rakefile', File.dirname(__FILE__))
Rake::Task.define_task :environment
end
describe 'rivendell::version' do
let :run_rake_task do
Rake::Task["rivendell::version"].reenable
Rake.application.invoke_task "rivendell::version"
end
it 'should display the right version' do
Rivendell.should_receive('VERSION')
run_rake_task
end
end
All tests for some reason pass, but if I change the should_receive call to
Rivendell.should_receive('DOESNTEXIST')
All tests pass in any case.
What am I doing wrong here?

Re-run failed unit tests in ruby

I have some unit tests written using Test::Unit::TestCase, with XML generated by ci_reporter. However, due to circumstances beyond my control, they may occasionally fluctuate, and randomly fail. I'd like to detect when a test fails, and attempt to re-run it.
I tried doing this by monkey-patching 'teardown' to check 'passed?', and re-running the tests on a failure. However, the XML output will still show the first failed case, and not the second (now passing) run.
This sounds a bit like the opposite of Multiple tests with minitest
Perhaps this is a possibility: Copy your test case in an own file. As an example, try the following test:
#store it as file 'testcase.rb'
gem 'test-unit'
require 'test/unit'
class X < Test::Unit::TestCase
def test_1
num = rand(10)
assert_true( num < 2, "Value is #{num}")
end
end
Then define your test call in a rake task:
require 'rake'
TEST_REPETION = 10
task :test do
success = false
TEST_REPETION.times{
stdout = `ruby testcase.rb`
if stdout =~ /Failure/
puts "Failure occured - redo the test"
else
puts 'Tests ok'
success = true
exit
end
}
puts "Stopped after #{TEST_REPETION} tries" unless success
end
Now the test is called, until the test succeed or TEST_REPETION are done.
Remarks:
Rake isn't needed, you may do the call without rake (My template was a rake task)
This works only, if your xml changes for each run (it must be regenerated before the test. else you test always the same).
You may store the test result (stdout) in a file and use it later to analyze, which tests failed and try to retest them.

How do I run Rake tasks within a Ruby script?

I have a Rakefile with a Rake task that I would normally call from the command line:
rake blog:post Title
I'd like to write a Ruby script that calls that Rake task multiple times, but the only solution I see is shelling out using `` (backticks) or system.
What's the right way to do this?
from timocracy.com:
require 'rake'
def capture_stdout
s = StringIO.new
oldstdout = $stdout
$stdout = s
yield
s.string
ensure
$stdout = oldstdout
end
Rake.application.rake_require 'metric_fetcher', ['../../lib/tasks']
results = capture_stdout {Rake.application['metric_fetcher'].invoke}
This works with Rake version 10.0.3:
require 'rake'
app = Rake.application
app.init
# do this as many times as needed
app.add_import 'some/other/file.rake'
# this loads the Rakefile and other imports
app.load_rakefile
app['sometask'].invoke
As knut said, use reenable if you want to invoke multiple times.
You can use invoke and reenable to execute the task a second time.
Your example call rake blog:post Title seems to have a parameter. This parameter can be used as a parameter in invoke:
Example:
require 'rake'
task 'mytask', :title do |tsk, args|
p "called #{tsk} (#{args[:title]})"
end
Rake.application['mytask'].invoke('one')
Rake.application['mytask'].reenable
Rake.application['mytask'].invoke('two')
Please replace mytask with blog:post and instead the task definition you can require your rakefile.
This solution will write the result to stdout - but you did not mention, that you want to suppress output.
Interesting experiment:
You can call the reenable also inside the task definition. This allows a task to reenable himself.
Example:
require 'rake'
task 'mytask', :title do |tsk, args|
p "called #{tsk} (#{args[:title]})"
tsk.reenable #<-- HERE
end
Rake.application['mytask'].invoke('one')
Rake.application['mytask'].invoke('two')
The result (tested with rake 10.4.2):
"called mytask (one)"
"called mytask (two)"
In a script with Rails loaded (e.g. rails runner script.rb)
def rake(*tasks)
tasks.each do |task|
Rake.application[task].tap(&:invoke).tap(&:reenable)
end
end
rake('db:migrate', 'cache:clear', 'cache:warmup')

Resources