I'm trying to set the logging level for the tests I'm running in test/unit
require 'test/unit'
require 'logger'
class MyMath
def self.adder(a,b)
a+b
end
end
class Tester < Test::Unit::TestCase
$logger = Logger.new($stdout)
def test_adder()
$logger.info "Starting Test"
assert_equal(4, MyMath.adder(2,2) )
$logger.info "Ending Test"
end
end
And the output is
Loaded suite ruby.test
Started
I, [2021-07-23T13:12:26.497311 #49542] INFO -- : Starting Test
I, [2021-07-23T13:12:26.497375 #49542] INFO -- : Ending Test
.
Finished in 0.000358 seconds.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 tests, 1 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
2793.30 tests/s, 2793.30 assertions/s
How do I get it to NOT print the logging messages? In the Test::Unit::UI::Console::TestRunner code it talks about
# Creates a new TestRunner for running the passed
# suite. If quiet_mode is true, the output while
# running is limited to progress dots, errors and
# failures, and the final result. io specifies
# where runner output should go to; defaults to
# STDOUT.
What is quiet_mode, and how can I set it?
I think your problem is that you need to set the log level of your logger accordingly.
$logger = Logger.new($stdout)
$logger.level = Logger::WARN
https://ruby-doc.org/stdlib-2.4.0/libdoc/logger/rdoc/Logger.html
Not sure if you use any framework so you could just set the log level in test like
if ENV["test"]
$logger.level = Logger::WARN
end
Related
I am using a rake task to run tests written in Ruby.
The rake task:
desc "This Run Tests on my ruby app"
Rake::TestTask.new do |t|
t.libs << File.dirname(__FILE__)
t.test_files = FileList['test*.rb']
t.verbose = true
end
I would like to create a timeout so that if any test (or the entire suite) hangs a timeout exception will be thrown and the test will fail.
I tried to create a new task that would run the test task with a timeout:
desc "Run Tests with timeout"
task :run_tests do
Timeout::timeout(200) do
Rake::Task['test'].invoke
end
end
The result was that a timeout was thrown, but the test continued to run.
I've been looking for something similar, and ended up writing this:
require 'timeout'
# Provides an individual timeout for every test.
#
# In general tests should run for less then 1s so 5s is quite a generous timeout.
#
# Timeouts can be overridden per-class (in rare cases where tests should take more time)
# by setting for example `self.test_timeout = 10 #s`
module TestTimeoutHelper
def self.included(base)
class << base
attr_accessor :test_timeout
end
base.test_timeout = 5 # s
end
# This overrides the default minitest behaviour of measuring time, with extra timeout :)
# This helps out with: (a) keeping tests fast :) (b) detecting infinite loops
#
# In general however benchmarks test should be used instead.
# Timeout is very unreliable by the way but in general works.
def time_it
t0 = Minitest.clock_time
Timeout.timeout(self.class.test_timeout, Timeout::Error, 'Test took to long (infinite loop?)') do
yield
end
ensure
self.time = Minitest.clock_time - t0
end
end
This module should be included into either specific test cases, or a general test case.
It works with a MiniTest 5.x
This code adds a timeout for entire suite:
def self.suite
mysuite = super
def mysuite.run(*args)
Timeout::timeout(600) do
super
end
end
mysuite
end
I have a problem with the testing the Sensu Plugin.
Everytime when I start rspec to test plugin it test it, but anyway at the end of test, the original plugin is started automatically. So I have in my console:
Finished in 0 seconds (files took 0.1513 seconds to load)
1 example, 0 failures
CheckDisk OK: # This comes from the plugin
Short explanation how my system works:
Plugin call system 'wmic' command, processes it, checks the conditions about the disk parameters and returns the exit statuses (ok, critical, etc)
Rspec mocks the response from system and sets into the input of plugin. At the end rspec checks the plugin exit status when the mocked input is given.
My plugin looks like that:
require 'rubygems' if RUBY_VERSION < '1.9.0'
require 'sensu-plugin/check/cli'
class CheckDisk < Sensu::Plugin::Check::CLI
def initialize
super
#crit_fs = []
end
def get_wmic
`wmic volume where DriveType=3 list brief`
end
def read_wmic
get_wmic
# do something, fill the class variables with system response
end
def run
severity = "ok"
msg = ""
read_wmic
unless #crit_fs.empty?
severity = "critical"
end
case severity
when /ok/
ok msg
when /warning/
warning msg
when /critical/
critical msg
end
end
end
Here is my test in Rspec:
require_relative '../check-disk.rb'
require 'rspec'
def loadFile
#Load template of system output when ask 'wmic volume(...)
end
def fillParametersInTemplate (template, parameters)
#set mocked disk parameters in template
end
def initializeMocks (options)
mockedSysOutput = fillParametersInTemplate #loadedTemplate, options
po = String.new(mockedSysOutput)
allow(checker).to receive(:get_wmic).and_return(po) #mock system call here
end
describe CheckDisk do
let(:checker) { described_class.new }
before(:each) do
#loadedTemplate = loadFile
def checker.critical(*_args)
exit 2
end
end
context "When % of free disk space = 10 >" do
options = {:diskName => 'C:\\', :diskSize => 1000, :diskFreeSpace => 100}
it 'Returns ok exit status ' do
begin
initializeMocks options
checker.run
rescue SystemExit => e
exit_code = e.status
end
expect(exit_code).to eq 0
end
end
end
I know that I can just put "exit 0" after the last example, but this is not a solution because when I will try to start many spec files it will exit after the first one. How to start only test, without running the plugin? Maybe someone can help me and show how to handle with such problem?
Thank you.
You can stub the original plugin call and optionally return a dummy object:
allow(SomeObject).to receive(:method) # .and_return(double)
you can put it in the before block to make sure that all assertions will share the code.
Another thing is that you are using rescue blocks to catch the situation when your code aborts with an error. You should use raise_error matcher instead:
expect { run }.to raise_error(SystemExit)
I am new into watir and I am using testunit for assertion.
My script looks like this:
Script1 -- has a test method which calls Script2
Script2 -- does all the work and validation. This has all assertion
When i run my test case I have to run Script1, it runs successfully but result shows 1 tests, 0 assertions, 0 failures, 0 errors, 0 skips.
Here is my code:
This is in my first file
require_relative 'RubyDriver'
require 'test/unit'
class RubyTest < Test::Unit::TestCase
def test_method
driver = RubyDriver.new("/home/pratik/study/UIAutomation/WatirScript.xlsx")
driver.call_driver
end
end
And this is part of anotner file
require_relative 'ExcelReader'
require_relative 'RubyUtility'
require "watir-webdriver"
require 'test/unit'
class RubyDriver < Test::Unit::TestCase
def take_action
value_property = #rubyutil.get_property("#{value}")
if value_property
value_prop = value_property.first.strip
value_value = value_property.last.strip
end
case "#{#rubyutil.get_string_upcase("#{keyword}")}"
when "VERIFY"
puts "verifying"
puts value_prop
puts value_value
object.wait_until_present
object.flash
if value_prop == "text"
assert_equal(object.text, value_value,"Text does not match")
# puts object.text.should == value_value
elsif value_prop == "exist"
value_boolean = value_value == "true" ? true : false
assert_equal(object.exists?,value_boolean,"Object does not exist")
# puts object.exists?.should == value_value
end
Everything is working fine except report which shows as
1 tests, 0 assertions, 0 failures, 0 errors, 0 skips.
Where is my number of assertions.
Any help please.
The problem is that you are calling your assertions within an instance of another class. If I recall correctly, assert increments the assertion count within its class instance. Therefore your assertion count is being incremented in your RubyDriver instance rather than the RubyTest instance. As a result, you get no assertions reported.
You need to do the assertions within the actual test case (ie test_method of RubyTest) that is being run by test/unit.
As an example, you could make RubyDriver include your driving logic and logic for retrieving values to test. RubyTest would then call RubyDriver to setup/get values and include your test logic.
class RubyTest < Test::Unit::TestCase
def test_method
# Do some setup using RubyDriver instance
driver = RubyDriver.new("/home/pratik/study/UIAutomation/WatirScript.xlsx")
driver.call_driver
# Use RubyDriver to get some value you want to test
some_value_to_test = driver.get_value_to_test
# Do the assertion of the value within RubyTest
assert_equal(true, some_value_to_test, "Object does not exist")
end
end
An alternative solution might be to pass the test case (RubyTest) to RubyDriver. Then have RubyDriver call the assertion methods using the RubyTest instance.
Here is a simplified working example where you can see that your assertion count is correctly updated. Note that the RubyTest instance is passed to RubyDriver and stored in the #testcase variable. All assertions are then run with the context of the #testcase - eg #testcase.assert(false), which ensures that the original test cases' assertion counts are updated.
require 'test/unit'
class RubyDriver < Test::Unit::TestCase
def initialize(file, testcase)
#testcase = testcase
super(file)
end
def action
#testcase.assert(false)
end
end
class RubyTest < Test::Unit::TestCase
def test_method
driver = RubyDriver.new("/home/pratik/study/UIAutomation/WatirScript.xlsx", self)
driver.action
end
end
I left the RubyDriver as a sub-class of Test::Unit::TestCase, though it seems a bit odd unless you also have actual tests in the RubyDriver.
I'm having problems using a global variable defined in the my test class, which then is referenced in the libraries file. I'm using Ruby 1.9.3p392 and test-unit 2.5.4.
This is the code that runs the tests:
require 'rubygems'
gem 'test-unit'
require 'test/unit'
require 'ci/reporter/rake/test_unit_loader'
load '../lib/functions.rb'
require 'watir'
class Test_002 < Test::Unit::TestCase
include Functions
class << self
def startup
#browser = Watir::Browser.new :ie
#browser.speed = :fast
end
def shutdown
#browser.close
end
end
def test_001_login
login('some_url', 'some_user', 'some_passw')
end
end
And this is part of the library that contains the login function:
require 'rubygems'
module Functions
def login(url, user, passw)
#browser.goto(url)
...
end
end
This is the output:
Started
E
===============================================================================
Error: test_001_login(Test_002)
NoMethodError: undefined method `goto' for nil:NilClass
(...)
23: end
24:
25: def test_001_login
=> 26: login('some_url', 'some_user', 'some_passw')
27: end
28:
29: end
===============================================================================
Finished in 3.0043 seconds.
1 tests, 0 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
0.33 tests/s, 0.00 assertions/s
Any ideas?
Your pre-test initialization code is not being run.
The TestUnit framework expects the setup code to be in a method named setup and the teardown code to be in a method named teardown
You have two options either rename the method startup to setup and the method shutdown to teardown, or, if you need setup/shutdown for some other purpose, create delegate methods:
def setup
startup
end
def teardown
shutdown
end
Instance variables (ie #browser) defined in the startup method will not be available to the tests. Based on this old forum thread, http://www.ruby-forum.com/topic/144884, it is by design:
That behavior is by design. The "test isolation" ideal implies you shouldn't need to work too hard to get a clean slate each time a test case starts. Otherwise a test could rely on a #value from the previous test, and could rely on it in a way you don't notice.
Of course any other persistent variable could ruin test isolation. We don't stopand restart Ruby between each test case. But at least when it happens the #instance variables won't be to blame.
One workaround that I have used I have used to use the same browser across tests was to use a class variable (ie ##browser). The startup would look like the following. The other methods would similarly have to be updated to use ##browser.
def startup
##browser = Watir::Browser.new :ie
##browser.speed = :fast
end
I have a few pure-JavaScript, client-side tests using PhantomJS. These I'd like to integrate with rake test.
Currently I use this:
namespace :test do
task :client do
basedir = Rails.root.join("test", "client")
sh "cd #{basedir} && phantomjs lib/run-qunit.js index.html"
end
end
task :test => "test:client"
However, this integration is far from perfect; if one of these tests fails, rake aborts. Also, in contrast to :units, :functionals and :integration, there is no summary of the issues at the end (e.g. "6 tests, 21 assertions, 1 failures, 0 errors").
I could extract that data easily enough, but how do I tell Rake to add it to the total test tally?
You are calling via sh a shell command. Ruby does not know, that it is a test.
In addition sh seems to stop, if a failure occurs.
You have to do two things: Catch the error and check the result of your call.
An example:
require 'rake'
$summary = Hash.new(0)
def mytest(name, cmd)
$summary['test'] += 1
sh cmd do |ok, res|
if ok
$summary['ok'] += 1
else
$summary['failure'] += 1
puts "#{cmd } failed"
end
end
end
namespace :test do
task :one do |tsk|
mytest(tsk.name, "dir")
end
task :two do |tsk|
mytest(tsk.name, "undefined_cmd")
end
task :summary do
p $summary
end
end
task :test => "test:one"
task :test => "test:two"
task :test => "test:summary"
shis called with a block to catch failures. Inside the block, I analyse the result (true for ok, false if the script stops with an error. The result is added to a summary hash.
For your use, you may adapt the code and split the code into two files: All test in one file. And the rake file get a Rake::TestTast.
Your test file may look like this:
gem 'test-unit'
require 'test/unit'
class MyTest < Test::Unit::TestCase
def test_one
assert_nothing_raised{
basedir = Rails.root.join("test", "client")
res = system("cd #{basedir} && phantomjs lib/run-qunit.js index.html")
assert_true(res)
}
end
def test_two
assert_nothing_raised{
res = `dir` #Test with windows
assert_match(/C:/, res) #We are in c:
}
end
end
This works only, if your test finish with a exit code. Perhaps you can use `` instead and get the output of your test for a detailed analyze.