How assertion counts are calculated in test unit - ruby

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.

Related

I want to call def setup method before all tests in minitest ruby

This is my code
class TestLogin < MiniTest::Test
def setup
#driver=Selenium::WebDriver.for :firefox
#driver.manage.window.maximize
#driver.navigate.to "http://google.com"
end
def test_case1
puts "testcase1"
end
def test_case2
puts "testcase2"
end
end
I want to run setup method only once for two testcases at the starting.
You can use minitest-hooks gem with before_all something like:
require "minitest/autorun"
require 'minitest/hooks/test'
class TestLogin < MiniTest::Test
include Minitest::Hooks
def before_all
puts "setup .."
end
def test_case1
puts "testcase1"
end
def test_case2
puts "testcase2"
end
end
Now when you run the test you should see something like:
Run options: --seed 58346
# Running:
setup ..
testcase1
.testcase2
.
Finished in 0.001259s, 1588.7504 runs/s, 0.0000 assertions/s.
2 runs, 0 assertions, 0 failures, 0 errors, 0 skips

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

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

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

Run unit test with Ruby 2.0 and minitest 5.5 without Gemfile

I was learning Ruby by reading Programming Ruby and there is this example code:
require_relative 'count_frequency'
require_relative 'words_from_string'
require 'test/unit'
class TestWordsFromString < Test::Unit::TestCase
def test_empty_string
assert_equal([], words_from_string(''))
assert_equal [], words_from_string(' ')
end
def test_single_word
assert_equal ['cat'], words_from_string('cat')
assert_equal ['cat'], words_from_string(' cat ')
end
def test_many_words
assert_equal ['the', 'cat', 'sat', 'on', 'the', 'cat'], words_from_string('the cat sat on the mat')
end
def test_ignore_punctuation
assert_equal ['the', "cat's", 'mat'], words_from_string("the cat's mat")
end
end
When I tried to run it, an error occured:
MiniTest::Unit::TestCase is now Minitest::Test.
More detailed error message:
I'm using ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14] and minitest (5.5.0, 5.4.3, 5.3.5, 4.3.2). I did some search and found that since minitest5.0, MiniTest::Unit::TestCase has changed to Minitest::Test. But I cannot do anything since it's in the source file of the gem. Some suggests that require minitest 4.** in Gemfile, but i'm just running a few scripts. There is no need for Gemfile I suppose. And I certainly don't want to uninstalling minitest5.**. So is there a way I could run this script with minitest5.5 and ruby 2.0?
The tests should still run. I have the same set up and even though I get that error, the tests are executed.
→ ruby --verbose etl_test.rb
MiniTest::Unit::TestCase is now Minitest::Test. From etl_test.rb:4:in `<main>'
Run options: --seed 61653
# Running:
....
Finished in 0.001316s, 3039.5137 runs/s, 3039.5137 assertions/s.
4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
classyhacker:~/dev/github/exercism/ruby/etl
→ rbenv versions
system
1.9.3-p448
2.0.0-p451
2.1.0
2.1.1
2.1.2
* 2.1.3 (set by RBENV_VERSION environment variable)
jruby-1.7.8
classyhacker:~/dev/github/exercism/ruby/etl
→ gem list | grep minitest
minitest (5.5.1, 5.4.3, 4.7.5)
My test looks like
require 'minitest/autorun'
require_relative 'etl'
class TransformTest < MiniTest::Unit::TestCase
def test_transform_one_value
old = { 1 => ['A'] }
expected = { 'a' => 1 }
assert_equal expected, ETL.transform(old)
end
require minitest/autorun is also the suggested way in rubydoc http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest.html

Selenium IDE export working strangely with Test::Unit and Ruby

I'm new to Selenium and I think I got Selenium IDE to work quite nicely, but something strange is happening (perhaps a bug) when I export Selenium IDE (2.5.0) Test Case to a Ruby Test::Unit / WebDriver test. My test works fine when I run it from Selenium IDE, but after I exported it to Ruby the following code doesn't work:
verify { assert_match /.*Welcome/, #driver.find_element(:xpath, "//title").text }
On Selenium IDE the same test is defined as:
Command: verifyText
Target: //title
Value: regexp:.*Welcome
and it works fine (attached screenshot)
Below is the Test::Unit error message for: verify { assert_match /.*Welcome/, #driver.find_element(:xpath, "//title").text } So there is some kind of problem with the RegEx I guess. The title should end with the word 'Welcome'.
jyrki#ubu:~/rails_projects/p3$ rake test test/selenium/employer_signup_ruby2_test.rb
Loaded suite /home/jyrki/.rvm/gems/ruby-2.1.0/bin/rake
Started
F
===============================================================================
Failure:
test_employer_signup_ruby2(EmployerSignupRuby2)
/home/jyrki/rails_projects/p3/test/selenium/employer_signup_ruby2_test.rb:17:in `teardown'
<[]> expected but was
<[#<Test::Unit::AssertionFailedError: <""> expected to be =~
</.*Welcome/>.>]>
diff:
+ [#<Test::Unit::AssertionFailedError: <""> expected to be =~
? [ ]
? </.*Welcome/>.>
===============================================================================
Finished in 12.747676835 seconds.
1 tests, 2 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
0.08 tests/s, 0.16 assertions/s
Run options: --seed 25544
# Running tests:
Finished tests in 0.003802s, 0.0000 tests/s, 0.0000 assertions/s.
0 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Below is the code that works apart from the one line of the code:
require "json"
require "selenium-webdriver"
gem "test-unit" #?
require "test/unit"
class EmployerSignupRuby2 < Test::Unit::TestCase
def setup
#driver = Selenium::WebDriver.for :firefox
#base_url = "http://0.0.0.0:3000/"
#accept_next_alert = true
#driver.manage.timeouts.implicit_wait = 30
#verification_errors = []
end
def teardown
#driver.quit
assert_equal [], #verification_errors
end
def test_employer_signup_ruby2
#driver.get(#base_url + "/employer_signup")
#driver.find_element(:id, "employer_first_name").clear
#driver.find_element(:id, "employer_first_name").send_keys "tester"
#driver.find_element(:id, "employer_last_name").clear
#driver.find_element(:id, "employer_last_name").send_keys "login-tester"
#driver.find_element(:id, "employer_email").clear
#driver.find_element(:id, "employer_email").send_keys "tester012345678901#test.com"
#driver.find_element(:id, "employer_password").clear
#driver.find_element(:id, "employer_password").send_keys "foobar"
#driver.find_element(:id, "employer_password_confirmation").clear
#driver.find_element(:id, "employer_password_confirmation").send_keys "foobar"
#driver.find_element(:name, "commit").click
verify { assert_match /.*Welcome/, #driver.find_element(:xpath, "//title").text }
end
def element_present?(how, what)
#driver.find_element(how, what)
#${receiver}.find_element(how, what)
true
rescue Selenium::WebDriver::Error::NoSuchElementError
false
end
def alert_present?()
#driver.find_element(how, what)
#${receiver}.switch_to.alert
true
rescue Selenium::WebDriver::Error::NoAlertPresentError
false
end
def verify(&blk)
yield
rescue Test::Unit::AssertionFailedError => ex
#verification_errors << ex
end
def close_alert_and_get_its_text(how, what)
alert = #driver.switch_to().alert()
#alert = ${receiver}.switch_to().alert()
alert_text = alert.text
if (#accept_next_alert) then
alert.accept()
else
alert.dismiss()
end
alert_text
ensure
#accept_next_alert = true
end
end
Actually, I can get the test to work (sort of) when I replace the one line of code with this:
verify { assert #driver.find_element(:xpath, '//title[contains(.,"Welcome")]') } #works!!
However if the “Welcome” text is missing (=test is failing), then the fix will remain in a loop indefinitely and I have interrupt (Ctrl + C) the test. So far this is the best fix I have found. If you know a better fix, please let me know, thanks :-)
My Gemfile has the following rails/selenium/test versions:
gem 'rails', '4.0.2'
gem 'selenium-webdriver', '~> 2.41.0' #this is the latest version
gem 'test-unit', '2.5.5'
gem 'rake', '10.2.2'
--
$ bundle show json
The gem json has been deleted. It was installed at:
/home/jyrki/.rvm/rubies/ruby-2.1.0/lib/ruby/gems/2.1.0/gems/json-1.8.1
Ruby 2.1.0
In addition, the export creates ruby code: ${receiver}.find_element(how, what) that doesn't work; so I needed to change it to #driver.find_element(how, what) to make it work.
Also, export creates a gem statement in addition to require statement for test-unit (lines 3-4):
gem "test-unit" #?
require "test/unit"
I might ask about this issue from Selenium Users Google Group as well
Btw, do you know if Selenium IDE exports work better with RSpec than Test::Unit?

Resources