NoMethodError: undefined method `run' for "unit/TestTestName.rb" when running testsuite in ruby - ruby

I want to write a testsuite to run my unit tests in ruby. So far I have come up with:
require 'test/unit/ui/console/testrunner'
require 'test/unit/testsuite'
class RunTests
def self.Run(arg)
test_suite = Test::Unit::TestSuite.new("All ATP Tests")
test_suite << 'unit/TestName1.rb'
test_suite << 'unit/TestName2.rb'
test_suite << 'unit/TestName3.rb'
arg used here in env setup
Test::Unit::UI::Console::TestRunner::new(test_suite).start
end
end
the tests all have the structure:
require 'test/unit'
class TestCalssName < Test::Unit::TestCase
def setup
end
def test_testcasename
end
def teardown
end
end
When I test the runner out in irb I get an error about undefined method run within a testcase:
irb(main):002:0> RunTests::Run("-env=qa-old")
Loaded suite All ATP Tests
Started
Finished in 0.002 seconds.
0 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
0.00 tests/s, 0.00 assertions/s
NoMethodError: undefined method `run' for "unit/TestTestName.rb":String
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/testsuite.rb:121:in `run_test'
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/testsuite.rb:53:in `run'
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/ui/testrunnermediator.rb:65:in `run_suite'
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/ui/testrunnermediator.rb:44:in `run'
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/ui/testrunnermediator.rb:100:in `with_listener'
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/ui/testrunnermediator.rb:40:in `run'
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/ui/testrunner.rb:40:in `start_mediator'
from /home/user/.gem/jruby/1.9/gems/test-unit-2.5.5/lib/test/unit/ui/testrunner.rb:25:in `start'
from /home/user/projects/verizon-smoke-tests/src/main/ruby/unit/RunATP.rb:27:in `Run'
from (irb):2:in `evaluate'
from org/jruby/RubyKernel.java:1119:in `eval'
from org/jruby/RubyKernel.java:1519:in `loop'
from org/jruby/RubyKernel.java:1282:in `catch'
from org/jruby/RubyKernel.java:1282:in `catch'
from /usr/local/jruby-1.7.9/bin/irb:13:in `(root)'
irb(main):003:0>
I tried putting a run method into the testcases but I still get the error (the exact same error about the run method being undefined). Am I missing something?
A

check if you're not calling run instead of Run, as Ruby is case-sensitive this might be the problem. We need the source code of "unit/TestTestName.rb" to get a better understanding of the problem.
EDIT
You are adding your TestCases as strings, like this :
test_suite << 'unit/TestName1.rb'
Since "unit/TestName1.rb" is a String, it has no run method that Ruby can call.
Ruby is expecting TestSuite objects in your test_suite object instead of Strings.
From Ruby Doc:
suite() :
Rolls up all of the test* methods in the fixture into one suite,
creating a new instance of the fixture for each method.
Instead, you should:
require on all your TestNameX.rb file
Add each TestCase to your TestSuite using the suite
It should be something like this:
require 'test/unit/ui/console/testrunner'
require 'test/unit/testsuite'
require 'unit/TestName1.rb'
require 'unit/TestName2.rb'
class RunTests
def self.Run(arg)
test_suite = Test::Unit::TestSuite.new("All ATP Tests")
test_suite << TestClassName1.suite
test_suite << TestClassName2.suite
arg used here in env setup
Test::Unit::UI::Console::TestRunner::new(test_suite).start
end
end
I am not sure about the TestRunner::new(test_suite).start, try:
Test::Unit::UI::Console::TestRunner.run(test_suite)
Feel free to have a look at the Ruby documentation
Test::Unit Test Suite

Related

Custom Rake task unable to be called twice in same Rakefile unike Rake::TestTask

I recently read an "older", 2009, article about how to make a Custom Rake tasks. So far it works for the first iteration, but I saw that Rake::TestTask can be called twice, so I figured I could do it, however my name attr_accessor is not picking up the symbol I'm passing to it.
require 'rake'
require 'rake/tasklib'
module Phil
class FooTask < Rake::TaskLib
attr_accessor :name
attr_accessor :data
attr_accessor :task_dependencies
def initialize(name = :task, task_dependencies)
#name = name
#data = nil
yield self if block_given?
#task_dependencies = task_dependencies
define
end
def define
desc "Run the #{#name} task"
task #name => #task_dependencies do
puts 'Some Test being Printed'
puts #data
sh 'echo blah'
end
self
end
end
end
Phil::FooTask.new :foo, [:call_me_first, :call_me_second]
task :call_me_first do
puts 'I am called first because I am a dependency'
end
task :call_me_second do
puts 'I am called second because Im also a dependency'
end
Phil::FooTask.new(:stuff) do |t|
t.data = 'I am a stuff task.'
end
The following is the results I get.
C:\Users\user01\Desktop
λ rake --tasks
rake foo # Run the foo task
rake stuff # Run the stuff task
C:\Users\user01\Desktop
λ rake foo
I am called first because I am a dependency
I am called second because Im also a dependency
Some Test being Printed
echo blah
blah
C:\Users\user01\Desktop
λ rake stuff --trace
** Invoke stuff (first_time)
rake aborted!
Don't know how to build task '{}' (see --tasks)
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task_manager.rb:58:in `[]'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:61:in `lookup_prerequisite'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:57:in `block in prerequisite_tasks'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:57:in `map'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:57:in `prerequisite_tasks'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:214:in `invoke_prerequisites'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:193:in `block in invoke_with_call_chain'
C:/tools/ruby23/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:187:in `invoke_with_call_chain'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/task.rb:180:in `invoke'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:152:in `invoke_task'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block (2 levels) in top_level'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `each'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:108:in `block in top_level'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:117:in `run_with_threads'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:102:in `top_level'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:80:in `block in run'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:178:in `standard_exception_handling'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/lib/rake/application.rb:77:in `run'
C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
C:/tools/ruby23/bin/rake:22:in `load'
C:/tools/ruby23/bin/rake:22:in `<main>'
Tasks: TOP => stuff
I'm not sure why the Rake task is failing. Even from reading the Rake's TestTask code, it seems I'm doing mostly everything correctly. I'll also say that I'm not a professional on Ruby and all the little tricks.
Keep arguments with default value at the end in method declaration!
The reason rake stuff is raising error is because of your Phil::FooTask.new(:stuff) do |t| call. Your initialize method expects two arguments. The error is in your declaration of the constructor where you've declared name = :task which has a default value of :task. However, the second parameter task_dependencies is expected. It is the second parameter that you're missing when initializing task with name :stuff.
Modify your initialize method declaration as follows:
def initialize(name = :task, task_dependencies = [])
Then you should see correct tasks when invoking rake -T:
rake foo # Run the foo task
rake stuff # Run the stuff task

Celluloid 0.17.3 giving unexpected "undefined method" error

I have started using Celluloid gem this morning for that first time. I am following this Railscasts tutorial and trying to figure things out.
I have a class called "SomeClass" and it has only one method. Here is the code:
require 'celluloid'
class SomeClass
include Celluloid
def initialize(name)
#name = name
end
def assholify()
puts "#{#name} has become an ASSHOLE."
end
end
When I create new instances of the class and call its method (with a bang i.e. "assholify!"), I am getting the undefined method 'assholify!', error. But Celluloid is supposed to trigger the method asynchronously when it is called with a bang. So here is how I am calling the method:
names = ['John', 'Tom', 'Harry']
names.each do |name|
n = SomeClass.new name
n.assholify!
end
Here is the full backtrace of the error:
I, [2016-09-09T11:28:02.488618 #3682] INFO -- : Celluloid 0.17.3 is running in BACKPORTED mode. [ http://git.io/vJf3J ]
/home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:42:in `rescue in check': undefined method `assholify!' for #<SomeClass:0x10897dc> (NoMethodError)
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:39:in `check'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/calls.rb:26:in `dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/call/sync.rb:16:in `dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/cell.rb:50:in `block in dispatch'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/cell.rb:76:in `block in task'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/actor.rb:339:in `block in task'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/task.rb:44:in `block in initialize'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/task/fibered.rb:14:in `block in create'
from (celluloid):0:in `remote procedure call'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/call/sync.rb:45:in `value'
from /home/railsdev/.rvm/gems/ruby-2.3.1/gems/celluloid-0.17.3/lib/celluloid/proxy/sync.rb:22:in `method_missing'
from some_class.rb:18:in `block in <main>'
from some_class.rb:16:in `each'
from some_class.rb:16:in `<main>'
Why am I getting this error? Is it the right way to call the function? Also how do I get rid of Celluloid 0.17.3 is running in BACKPORTED mode. warning?
The undefined method error occurred because actor methods are not called with a bang in the recent versions of celluloid gem. Instead you call the method like this: n.async.assholify. So here is what the code should look like:
names = ['John', 'Tom', 'Harry']
names.each do |name|
n = SomeClass.new name
n.async.assholify # Instead of "n.assholify!"
end
For "Celluloid 0.17.0 is running in BACKPORTED mode" warning, take a look at this wiki. Backported Mode is the default, for a limited time. If you use require 'celluloid/current' instead of require 'celluloid', you should not see this warning.

If I'm testing an rspec extension, how do I suppress the results of tests which fail as part of the test?

I'm trying to write specs for an extension to rspec.
This is the gist of what I'm trying to test:
require 'rspec-let-and-after-extension'
RSpec.describe "let(...).and_after" do
it 'is called if the `let` is invoked even if the example fails' do
call_order = []
RSpec.describe do
let(:foo) { }.and_after { call_order << :and_after }
it { foo; call_order << :example; raise 'failed!' }
end.run
expect(call_order).to eq [:example, :and_after]
end
end
One of the important behaviours is that if running the example fails, the cleanup code still runs. So I test this by recording the order of the calls and raising an exception from the example.
Problem is, when I run it, it sees this block as a second example, which then fails with errors:
.F
Failures:
1)
Got 0 failures and 2 other errors:
1.1) Failure/Error: it { foo; call_order << :example; raise 'failed!' }
RuntimeError:
failed!
# ./spec/spec.rb:43:in `block (4 levels) in <top (required)>'
# ./spec/spec.rb:44:in `block (2 levels) in <top (required)>'
1.2) Failure/Error: it { foo; call_order << :example; raise 'failed!' }
RuntimeError:
failed!
# ./spec/spec.rb:43:in `block (4 levels) in <top (required)>'
Finished in 0.00167 seconds (files took 0.08011 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/spec.rb:43 #
As you can see, the output did have one dot, so the actual example passed. But then there is an F, because it has seen the internal example, run that, and unsurprisingly that one failed.
How do I make rspec not see this nested example as one of the examples it's supposed to run, so that this example completes with a single dot?
(If you're wondering about what the rspec devs themselves do about their tests, it looks like they use cucumber. Do they use cucumber because they couldn't figure this out either? :))
You can use the new sandboxing API (available in 3.2+).
RSpec.configure do |rspec|
rspec.around do |ex|
RSpec::Core::Sandbox.sandboxed do |config|
# re-configure any configuration defined by your extension here
# before allowing the example to run. The sandbox runs with a fresh
# config instance, which means any configuration you have set in
# `rspec-let-and-after-extension` will not apply while the example
# is running.
# config.extend MyExtensionModule
ex.run
end
end
end

How to define Ruby Test::Unit testcase with `must`

I had a test case of the following form:
require 'test/unit'
class SomeTests < Test::Unit::TestCase
def test_should_do_action
assert true
end
end
and have re-written it using must as suggested in the book A Test::Unit Trick to Know About:
require 'test/unit'
class SomeTests < Test::Unit::TestCase
must "do action" do
assert true
end
end
And when I run it, I get an undefined method 'must' error shown as follows:
SomeTests.rb:3:in `<class:SomeTests>': undefined method `must' for SomeTests:Class (NoMethodError) from
SomeTests.rb:2:in `<top (required)>' from
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require' from
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require' from
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake/rake_test_loader.rb:10:in `block (2 levels) in <main>' from
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake/rake_test_loader.rb:9:in `each' from
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake/rake_test_loader.rb:9:in `block in <main>' from
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake/rake_test_loader.rb:4:in `select' from
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake/rake_test_loader.rb:4:in `<main>' rake aborted! Command failed with status (1): [ruby -w -I"lib" -I"/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0" "/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake/rake_test_loader.rb" "test/**/*Tests.rb" ]
Tasks: TOP => default => test (See full trace by running task with --trace)
I thought that must might be a part of minitest, so I required 'minitest/unit' instead, but I still get an error. I also assume that must keyword isn't part of rspec, which I'm not using yet.
How do I get this to work properly?
It looks like that method is not provided out of the box, but was developed by a third party. You need to add code described here.

Why do I get "Undefined method ::new" in simple classes?

I am writing an ATM-system-like socket/server solution. I would appreciate if someone could tell me what I'm missing. For some reason, I get the following error running my stub test suite:
# Running tests:
.E
Finished tests in 0.002411s, 829.4384 tests/s, 414.7192 assertions/s.
1) Error:
test_0001_connects_to_a_host_with_a_socket(AtmClient::connection):
NoMethodError: undefined method `new' for #<SpoofServer:0x9dce2dc #clients=[], #server=#<TCPServer:fd 5>>
/media/wildfyre/Files/Programming/KTH/progp/Atm/spec/client/SpoofServer.rb:12:in `start'
/media/wildfyre/Files/Programming/KTH/progp/Atm/spec/client/client_spec.rb:12:in `block (3 levels) in <top (required)>'
2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
My minispec file is:
require_relative '../spec_helper.rb'
require_relative '../../lib/AtmClient.rb'
require_relative 'SpoofServer.rb'
describe AtmClient do
it "can be created with no arguments" do
AtmClient.new.must_be_instance_of AtmClient
end
describe 'connection' do
it "connects to a host with a socket" do
spoof = SpoofServer.new.start
client = AtmClient.new.connect
spoof.any_incoming_connection?.must_be true
spoof.kill
end
end
end
My SpoofServer file is:
require 'socket'
class SpoofServer
def initialize
end
def start
#clients = []
#server = TCPServer.new 1234
#listener_thread = new Thread do
#clients.add #server.accept
end
end
def any_incoming_connection?
#clients.size > 0
end
def kill
#listener_thread.exit
#clients.each {|c| c.close}
end
end
As you can read in the trace of the calls stack:
NoMethodError: undefined method `new' for #<SpoofServer:...>
/.../spec/client/SpoofServer.rb:12:in `start'
The error is inside the start method defined in SpoofServer.rb, at line 12, the wrong line is:
#listener_thread = new Thread do
That should be:
#listener_thread = Thread.new do
As you have written it, what you are actually doing is to calling the new method passing the Thread class as argument. Since no new method is defined for instances of the SpoofServer class you get the NoMethodError exception.
In body of instance method SpoofServer#start, you can't call the class method SpoofServer.new by new.

Resources