minitest + capybara how to do save_and_open_page when there is an error - ruby

When using rspec I usually do something like:
if ENV['OPEN_ERRORS']
shown_error_pages = 0
config.after :each do
if RSpec.current_example.exception != nil and shown_error_pages == 0
shown_error_pages += 1
save_and_open_page
end
end
end
e.g. OPEN_ERRORS=1 bundle exec rspec
How can I do something like this with minitest?

You can do this in a teardown or after_teardown block by checking !passed?
The capybara-screenshot gem provides this behavior and is compatible with both RSpec and minitest, you can see how it implements the behavior here - https://github.com/mattheworiordan/capybara-screenshot/blob/master/lib/capybara-screenshot/minitest.rb

Related

Ruby Minitest assert_equal fails

I have a gemfile with the following:
# frozen_string_literal: true
source "https://rubygems.org"
gem 'cucumber'
gem 'minitest', '~> 5.10', '>= 5.10.3'
gem 'minitest-focus'
gem 'minitest-reporters', '~> 1.1.9'
gem 'rspec'
...
A Cucumber .env file with this to load and require the gems:
require 'bundler'
Bundler.require
And a Ruby file with the following:
require 'minitest/autorun'
require_relative './../../../../RubyProjects/mksta-common/common'
class VerifyApi < MiniTest::Test
include Common
def initialize(has_authorization)
#has_authorization = has_authorization
end
def test_id_correct
assert_equal(20, 20)
end
end
I am receiving this error when attempting to do that assert:
undefined method `+' for nil:NilClass
In Assertions.rb:
def assert_equal exp, act, msg = nil
msg = message(msg, E) { diff exp, act }
result = assert exp == act, msg
if exp.nil? then
if Minitest::VERSION =~ /^6/ then
refute_nil exp, "Use assert_nil if expecting nil."
else
where = Minitest.filter_backtrace(caller).first
where = where.split(/:in /, 2).first # clean up noise
warn "DEPRECATED: Use assert_nil if expecting nil from #{where}. This will fail in Minitest 6."
end
end
result
end
def assert test, msg = nil
self.assertions += 1
unless test then
msg ||= "Expected #{mu_pp test} to be truthy."
msg = msg.call if Proc === msg
raise Minitest::Assertion, msg
end
true
end
Error occurs at the line: "self.assertions += 1" so i am not sure where "assertions" is not being set..
I am wondering if my require process is incorrect, or if i am missing a requirement. Or perhaps Cucumber / Rspec is getting in the way? Any help would be appreciated.
Well, the problem is when you initialize VerifyApi, you did not initialize MiniTest::Test. So the self.assertions is nil.
To solve this problem, you just need to add one more line in the initialize function
super(name)
Of course, you need add one parameter in the function.

Does minitest provide a "test" directive?

In Rails I can use the test keyword for my tests which I find very attractive and a bettter choice to Rspec's verbosity.
Example:
class TestMyClass < ActionController::TestCase
test 'one equals one' do
assert 1 == 1
end
end
At the moment I am creating a gem and I want to follow the same way for my tests - by using the test method. I tried inheriting from Minitest and UnitTest and the latter seems to work. However I was under the impression that Rails uses Minitest. So does Minitest actually provide a test directive?
This works:
class TestMyClass < Test::Unit::TestCase
test 'one equals one' do
assert 1 == 1
end
end
This gives me "wrong number of arguments for test":
class TestMyClass < Minitest:Test
test 'one equals one' do
assert 1 == 1
end
end
No, Minitest runs ordinary methods with names started from 'test_'.
Method test from ActionController::TestCase is provided by Rails and works as a simple wrap for 'test_*' methods. It converts this
test 'truish' do
assert true
end
to this
def test_truish
assert true
end
Also it checks if the body of the test was defined, if it wasn't, it will show an error message.

Use "vanilla" assert in Rspec?

How can someone use vanilla assert in Rspec?
require 'rspec'
describe MyTest do
it 'tests that number 1 equals 1' do
assert 1 == 1
end
end
The error I get:
undefined method `assert' for
#<RSpec::ExampleGroups::Metadata::LoadFile:0x00000002b232a0>
Notice that I don't want to use assert_equal, eq, should, or other mumbo jumbo.
You can do this pretty easily:
require 'rspec/core'
require 'test/unit'
describe 'MyTest' do
include Test::Unit::Assertions
it 'tests that number 1 equals 1' do
assert 1 == 2
end
end
(if you want to be able to run the tests by doing ruby foo.rb then you'll need to require rspec/autorun too). This pulls in all of those assertions. If you really don't want any extra assertions, just define your own assert method that raises an exception when the test should fail.
Conversely you can easily use rspec's expectation syntax outside of rspec by requiring rspec/expectations - rspec3 is designed to be modular.
Configure RSpec to use MiniTest
RSpec.configure do |rspec|
rspec.expect_with :stdlib
end
Then you can use all the asserts offered by MiniTest from the standard library.
...or Wrong
Alternatively, you can use Wrong if you like asserts with a block:
require 'wrong'
RSpec.configure do |rspec|
rspec.expect_with Wrong
end
describe Set do
specify "adding using the << operator" do
set = Set.new
set << 3 << 4
assert { set.include?(3) }
end
Inspired by this blog article on RSpec.info.

Minitest - Tests Don't Run - No Rails

I'm just starting a small project to emulate a Carnival's ticket sales booth and one of the guidelines was to test that a user can enter the number of tickets. The program runs in the console and I eventually (hopefully) figured it out how to implement this test thanks to #Stefan's answer on this question.
The problem is that now, when I run the test file, minitest says:
0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
I get the same result when I try to run the test by name using ruby path/to/test/file.rb --name method-name. I'm not sure if this is because my code is still faulty of if it's because I've set up minitest incorrectly. I've tried to look up similar problems on SO but most questions seem to involve using minitest with rails and I just have a plain ruby project.
Here's my test file:
gem 'minitest', '>= 5.0.0'
require 'minitest/spec'
require 'minitest/autorun'
require_relative 'carnival'
class CarnivalTest < MiniTest::Test
def sample
assert_equal(1, 1)
end
def user_can_enter_number_of_tickets
with_stdin do |user|
user.puts "2"
assert_equal(Carnival.new.get_value, "2")
end
end
def with_stdin
stdin = $stdin # global var to remember $stdin
$stdin, write = IO.pipe # assign 'read end' of pipe to $stdin
yield write # pass 'write end' to block
ensure
write.close # close pipe
$stdin = stdin # restore $stdin
end
end
In a file called carnival.rb in the same folder as my test file I have
Class Carnival
def get_value
gets.chomp
end
end
If anyone can help figure out why the test is not running I'd be grateful!
By convention, tests in Minitest are public instance methods that start with test_, so the original test has no actual test methods. You need to update your test class so that the methods with assertions follow the convention as:
class CarnivalTest < Minitest::Test
def test_sample
assert_equal(1, 1)
end
def test_user_can_enter_number_of_tickets
with_stdin do |user|
user.puts "2"
assert_equal(Carnival.new.get_value, "2")
end
end
# snip...
end
Yeah always start all your tests with test_ so it knows that you want to that function/method
class CarnivalTest < MiniTest::Test
def test_sample
assert_equal(1, 1)
end
def test_user_can_enter_number_of_tickets
with_stdin do |user|
user.puts "2"
assert_equal(Carnival.new.get_value, "2")
end
end
and that should work for you

How assertion counts are calculated in test unit

Method 1:-
test.rb
class Test < Test::Unit::TestCase
def test_sample
assert_true(test)
assert_equal(a,b)
end
end
Result:-
Finished in 38.329532529 seconds.
1 tests, 2 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
Method 2:-
test.rb
class Test < Test::Unit::TestCase
require 'helper'
include AssertionHelper
def test_sample
test_assertion
end
end
helper.rb
include Test::Unit::Assertions
module AssertionHelper
def test_assertion
assert_true(test)
assert_equal(a,b)
end
end
Result:-
Finished in 38.329532529 seconds.
1 tests, 2 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
Method 3:-
test.rb
class Test < Test::Unit::TestCase
require 'helper'
def test_sample
AssertionHelper.test_assertion()
end
end
helper.rb
include Test::Unit::Assertions
module AssertionHelper
def self.test_assertion
assert_true(test)
assert_equal(a,b)
end
end
Result:-
Finished in 38.329532529 seconds.
1 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
When using Method 3, I am getting assertion count as "0" instead of "2".
Is it possible for me to get assertion count as 2 using Method 2 ?
You can pass your current TestCase to your module, like this:
sample_test.rb:
require 'test-unit'
require 'helper'
def a; true ; end
def b; true ; end
def test; true ; end
class SampleTest < Test::Unit::TestCase
def test_sample
AssertionHelper.my_assertion(self)
end
end
helper.rb:
module AssertionHelper
def self.my_assertion(test_case)
test_case.instance_exec do
assert_true(test)
assert_equal(a, b)
end
end
end
Sorry, but I can't reproduce your situation, could you please provide Test::Unit version and your ruby version? Best of all would be your Gemfile with Gemfile.lock. The following setup works for me (I use ruby 2.2.0 and test-unit 3.0.8):
ruby-2.2.0 in ~/projects/test-unit ♥ tree
.
├── Gemfile
├── Gemfile.lock
└── test
├── helper.rb
└── sample_test.rb
1 directory, 4 files
ruby-2.2.0 in ~/projects/test-unit ♥ cat Gemfile
# A sample Gemfile
source "https://rubygems.org"
# gem "rails"
gem 'test-unit', '~> 3.0.8'
ruby-2.2.0 in ~/projects/test-unit ♥ cat Gemfile.lock
GEM
remote: https://rubygems.org/
specs:
power_assert (0.2.2)
test-unit (3.0.8)
power_assert
PLATFORMS
ruby
DEPENDENCIES
test-unit (~> 3.0.8)
sample_test.rb:
require 'test-unit'
def a; true ; end
def b; true ; end
def test; true ; end
class SampleTest < Test::Unit::TestCase
require 'helper'
include AssertionHelper
def test_sample
my_assertion
end
end
helper.rb:
module AssertionHelper
def my_assertion
assert_true(test)
assert_equal(a, b)
end
end
Running testrb gives 2 assertions, as expected.
ruby-2.2.0 in ~/projects/test-unit ♥ testrb
Loaded suite .
Started
.
Finished in 0.000828 seconds.
1 tests, 2 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
1207.73 tests/s, 2415.46 assertions/s
ruby-2.2.0 in ~/projects/test-unit ♥
UPDATE: This is actually strange that you don't get any error (on your method 3), because I get this: NoMethodError: undefined method 'assert_true' for AssertionHelper:Module and this is true, since AssertionHelper doesn't implement any other methods, you can't run any assert_* methods on it. Just use my code above (your method 2) and you should be fine. If you're still curious what can be done, have a look at Test::Unit::Assertions, there's also a lot of built-in assertions defined, maybe you find that useful.
Or, better, use MiniTest or RSpec, since Test::Unit is deprecated and is left in standard library only for legacy test suites.

Resources