I have been trying to use the minitest-reporters gem to alter the output style of Ruby's builtin minitest testing library. However, it does not actually change the output.
It should be noted that I am not using Rails or Rake, but I didn't think that would make a difference. I am simply trying to test a Ruby command-line program that I have written.
Here's a dumb little test case (let's call it dumbtest.rb) that I was trying out:
require 'minitest/autorun'
require 'minitest/reporters'
Minitest::Reporters.use! [Minitest::Reporters::DefaultReporter.new(:color => true), Minitest::Reporters::SpecReporter.new]
describe "MiniTest demo" do
describe "when asked about the number 2" do
it "should be equal to the number 2" do
2.must_equal 2
end
end
end
When I run the test, it just produces the default minitest output (i.e. colorless, no descriptions of passing tests, etc.):
$ ruby -Ilib:test dumbtest.rb
Run options: --seed 48983
# Running:
.
Finished in 0.001356s, 737.6595 runs/s, 737.6595 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
With minitest-reporters enabled, I expect the output to look something more like this (i.e. list both passing and failing tests as opposed to just failing, the word PASS is colored green, the final summary is color-coded, etc.):
There are no runtime errors. It's just not working for me. Any idea why?
Related
given the following test:
require 'minitest/spec'
require 'minitest/autorun'
describe 'stuff' do
def foo
assert false
end
it "should show stack trace" do
foo
end
end
I am getting an error saying failed assertion on line 6, is it possible to show full stack trace so I know it got called within the it statement?
With default Minitest, you only get the (abbreviated) stack trace when an exception is raised. Try the Minitest::Reporters gem if you want to be able to customize your output easily - including also showing a partial stack trace for failures.
The minitest failure message should show which test has failed - in the case of an exception being raised then a stack trace would be useful.
So, if I add another test calling the foo method then I will also see that test fail, and the same line.
describe 'stuff' do
def foo
assert false
end
it "should show stack trace" do
foo
end
it "will not show stack trace" do
foo
end
end
Then I see;
Finished in 0.001372s, 1457.7259 runs/s, 1457.7259 assertions/s.
1) Failure:
stuff#test_0001_should show stack trace [t.rb:6]:
Failed assertion, no message given.
2) Failure:
stuff#test_0002_will not show stack trace [t.rb:6]:
Failed assertion, no message given.
You would generally use a custom method in a test to verify common functionality;
it 'works like a Widget' do
widget = WidgetMaker.do_something
verify_widget widget
end
private
def verify_widget(widget)
assert_ # etc ...
end
It seems -b is no longer a valid option for rake test. I'm running minitest (5.13.0).
Use -t instead:
rake test -h
...
-t, --trace=[OUT] Turn on invoke/execute tracing, enable full backtrace. OUT can be stderr (default) or stdout.
As #Rafael mentioned in the comments, there's the -b flag.
This flag is added by the rails extension to minitest, so it is a minitest option, but requires rails.
The correct order of the options is this:
rails test -b #...
Check it by calling the help:
> rails test -h
Usage: rails test [options] [files or directories]
You can run a single test by appending a line number to a filename:
rails test test/models/user_test.rb:27
You can run multiple files and directories at the same time:
rails test test/controllers test/integration/login_test.rb
By default test failures and errors are reported inline during a run.
minitest options:
-h, --help Display this help.
--no-plugins Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS).
-s, --seed SEED Sets random seed. Also via env. Eg: SEED=n rake
-v, --verbose Verbose. Show progress processing files.
-n, --name PATTERN Filter run on /regexp/ or string.
--exclude PATTERN Exclude /regexp/ or string from run.
Known extensions: simplecov, minitest_reporter, rails, pride
-w, --warnings Run with Ruby warnings enabled
-e, --environment ENV Run tests in the ENV environment
-b, --backtrace Show the complete backtrace
-d, --defer-output Output test failures and errors after the test run
-f, --fail-fast Abort test run on first failure or error
-c, --[no-]color Enable color in the output
-p, --pride Pride. Show your testing pride!
I have a Ruby program that fails at runtime, but works when I test it with RSpec. I know the cause of the bug and how to fix it (see below), but I can't figure out how to build a failing RSpec test which proves the existence of the bug.
Imagine the following Ruby:
foobar.rb
class Foobar
attr_reader :fruit
def initialize
#fruit = Set.new ["Apple", "Banana", "Kiwi"]
end
end
The above code uses a Set, but it fails to "require 'set'". This causes it to fail at runtime:
$ irb
> require './foobar.rb'
> f = Foobar.new
NameError: uninitialized constant Foobar::Set
Before fixing the oversight, I wanted to build a simple RSpec test that proves the bug. My test looks like this:
foobar_spec.rb
require 'rspec'
require './foobar.rb'
describe Foobar do
it "can be initialized" do
expect { Foobar.new }.to_not raise_error
end
end
Running the test, I was surprised to see that it passes:
$ rspec foobar_spec.rb
.
Finished in 0.00198 seconds
1 example, 0 failures
After a little digging, I learned that RSpec loads Set for itself. This has the consequence of making Set available to the code it tests, and in my case concealing a bug.
I had the idea of "unloading/unrequiring" Set in my test. The closest I came was this code:
Object.send(:remove_const, :Set)
That indeed causes the test to fail, but unfortunately it also prevents Set from being loaded again by a future 'require', meaning it continued to fail even after I added require 'set' inside foobar.rb.
Is there a better way to unload gems at runtime? If not, what can I do to make this test fail as it should?
require 'rspec'
describe 'foobar.rb' do
it "can instantiate Foobar" do
`ruby -e 'Foobar.new' -r./foobar.rb`
$?.exitstatus.should == 0
end
end
works for the one case you mentioned. That said, I wouldn't recommend this approach. To cover all the cases where a class is referenced, you'd need to run all your specs this way, since the class reference could appear anywhere in your code.
I'm creating a Ruby (not Rails) script and I have to test using standard Rails unit tests and Cucumber. I can't use RSpec.
So how do I test a ruby script with Cucumber and Rails Test::Unit? Is it possible?
Here, I created a complete example including a Rakefile for convenience. The file structure is this:
./notepad.rb
./Rakefile
./test
./test/test_notepad.rb
./features
./features/add_note.feature
./features/step_definitions
./features/step_definitions/add_note_step.rb
In fact this example doesn't even use classes, so you can really test typical "Scripts" with it. File contents are here: http://pastebin.com/sJUP7VSA
So in the end you can do this:
$ rake test
Finished tests in 0.001368s, 730.9942 tests/s, 1461.9883 assertions/s.
1 tests, 2 assertions, 0 failures, 0 errors, 0 skips
$ rake cucumber
1 scenario (1 passed)
2 steps (2 passed)
0m0.002s
Cheers, Philip
I have a suite of RSpec tests I want to group under the following hierarchy:
tests/
featA/
t1.rb
t2.rb
featB/
t3.rb
but when I run
$ rspec tests
I get the following:
rspec tests
No examples were matched. Perhaps {:unless=>#<Proc:0x00007f318919cc08#/usr/lib/ruby/gems/1.8/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:51>, :if=>#<Proc:0x00007f318919cdc0#/usr/lib/ruby/gems/1.8/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:50>} is excluding everything?
Finished in 0.00003 seconds
0 examples, 0 failures
I feel like I'm going mad, but there doesn't seem to be a way to get RSpec to recursively glob for test files? Does this functionality exist?
EDIT:
I have a workaround by doing this:
$ rspec `find tests -name "*.rb"`
but I suspect I shouldn't have to. Am I right?
You've exposed an oversight on my part! In rspec-1, you could say this:
spec test --pattern "**/*.rb"
But the --pattern option is missing in rspec-2. I've just added it (in development) and it will be included in the rspec-2.6.0 release.
I usually manage running RSpec on my specs via rake. The relevant portion of my Rakefile looks something like this:
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec) do |t|
t.rspec_opts = ['--color', '-f progress', '-r ./spec/spec_helper.rb']
t.pattern = 'spec/**/*_spec.rb'
t.fail_on_error = false
end
Now rake spec runs RSpec with the appropriate options; you'll need to change t.pattern to match the specs you want to run.
Be sure to check out the RSpec2 site for more information.
I was working with the lotrepls Ruby interpreter, and I want like to write tests in the interpreter that I can then write Ruby code to pass. In Python, I can write doctests and then write code to pass the doctests. For example:
>>> b
1
This tests that b=1, and entering b=1 will get this doctest to pass.
Is there a similar way to write tests in a Ruby interpreter, execute them, write code to pass the tests, and then execute the test again? Is there a Ruby doctest equivalent? For my application, I will execute tests and code in a hosted interpreter like lotrepls rather than install something on my local machine.
There's RubyDocTest, but I'd encourage you to look at something like RSpec or another modern BDD/TDD framework.
It's pretty easy to write tests there too, and you get access to complex and/or custom assertions that you can't really get in a doctest. For instance, here's a simple set of tests for a baseball scoring app:
describe BaseballScorer do
before :each do
#s = Scorer.new(Game.new)
end
it "should score a 0-0 game when no runs are hit" do
#s.home.score.should == #s.away.score.should == #s.total_runs
end
it "should record runs that are hit" do
#s.game.run_hit(:away)
#s.away.runs.should == #s.away.score.should == 1
end
# ...
This is a little old post but I faced the same problem some months ago.
John's answer is correct but if you want to use something similar to a irb session you could try byexample, in particular it supports Ruby
For example you can write a Markdown doc like this:
This is an awesome expression:
```ruby
>> 1 + 2
=> 3
```
Then you just run from the shell
$ byexample -l ruby your-markdown-doc.md
[PASS] Pass: 1 Fail: 0 Skip: 0
You could also embed the test inside a Ruby comment like
# square 2
# => 4
def square x
x * x
end
And that's it. The example is executed and checked so your doc works as regression test as well.
Disclaimer: Like I said, I had the same desire to do TDD in Ruby so I wrote byexample. I really hope than others find it as much as useful and I do.