Why do I not see the thrown exceptions in a Cucumber "Around"? - ruby

I have a set of cucumber tests that get run on a build server.
I often want faster feedback than the server directly provides and so I watch the console output as it runs. I was wanting a way of identifying any failing test with a single search term so I modified our Around to print "Failed Test" on any exception, but Ruby doesn't seem to be handing the exception back up to the around. I've verified this by having puts statements after the begin ... end.
Does anyone know why this is happening or a way of wrapping any exception thrown from a failing test in a begin?
Around() do |scenario, block|
begin
Timeout.timeout(0.1) do
block.call
end
rescue Timeout::Error => e
puts "Failed Test"
puts caller
rescue Exception => e
puts "Failed Test"
raise e
end
end

Looking at cucumber 1.3.12 it actually rescues any exceptions from scenario steps. So you can't see them in any way without modifying cucumber gem.
See my answer on how to put a debug hook in that place for more information:
https://stackoverflow.com/a/22654786/520567

Have you tried disabling Cucumber's exception capturing with the #allow-rescue tag?
#allow-rescue: Turns off Cucumber’s exception capturing for the tagged scenario(s). Used when the code being tested is expected to raise and handle exceptions.
https://github.com/cucumber/cucumber/wiki/Tags

Related

ruby selenium-webdriver quit before exception is rescued

Recently, I am working on mobile automation using appium+selenium in ruby. But stopped by the following issue: selenium driver is quit automatically (mobile app is closed) every time an exception happens. This will result in that the following code to access the driver will fail after I manage to rescue the exception.
e.g.
begin
#driver.find_element(:xpath, "//window[1]/button[27]")
rescue
#driver.find_element(:xpath, "//window[1]/navigationBar[1]/button[2]").click
end
Does anyone have this issue as well?
According to http://www.ruby-doc.org/core-2.1.1/doc/syntax/exceptions_rdoc.html "By default StandardError and its subclasses are rescued. You can rescue a specific set of exception classes (and their subclasses) by listing them after rescue:
begin
# ...
rescue ArgumentError, NameError
# handle ArgumentError or NameError
end
I assume you are waiting for something like ElementNotVisibleException. So, add type of exception after rescue. Something like rescue ElementNotVisibleException.

How can I rescue a Errno::ECONNRESET

I have a script that spiders a website, its based on Mechanize and seems to be working great except for what seems like an error I can't catch. 'Errno::ECONNRESET' This seems to reset the connection and print the error, but it doesn't seem to raise an exception. What is the best way to deal with this? I will put the program flow in pseudo code below.
while LinksQue.notEmpty
begin
mech.get(LinksQue.nextLink)
rescue Mechanize::ResponseCodeError => e
puts e.response_code
puts "this is a bad link"
rescue Errno::ECONNRESET
#This doesn't work
end
end
Part of my problem is that my method for marking a link as 'visited' or as a 'bad link' is a DB so unless I can update the DB in a rescue block it will just keep trying the same link again and again.

get the backtrace in a sinatra app

Im trying to get the backtrace in sinatra in case of an error.
I know rails has one in
Rails.respond_to?(:backtrace_cleaner)
and I saw that sinatra is suppose to have one (by default enabled) in STDERR
So i tried
STDERR.inspect
and I got #<IO:<STDERR>>
When rescuing the exception, catch the exception object.
begin
raise "hello"
rescue => e
e.backtrace
end
In Ruby you can call a method caller at any place and get a full backtrace as an array.

How to "ignore" caught exceptions?

I use rufus scheduler to run overnight test scripts by calling my functions.
Sometimes I can see "scheduler caught exception:" a message that threw some of my functions. Then scheduler stops execution of following test cases.
How can I make it so scheduler runs all test cases regardless of any exception caught?
This is called "exception swallowing". You intercept an exception and don't do anything with it.
begin
# do some dangerous stuff, like running test scripts
rescue => ex
# do nothing here, except for logging, maybe
end
If you do not need to do anything with the exception, you can omit the => ex:
begin
# do some dangerous stuff, like running test scripts
rescue; end
If you need to rescue Exceptions that don't subclass from StandardError, you need to be more explicit:
begin
# do some dangerous stuff, like running test scripts
rescue Exception
# catches EVERY exception
end
I will sometimes use the fact that you can pass blocks to a method, and I have the method rescue errors, and my code can continue on its way.
def check_block
yield
rescue NoMethodError => e
<<-EOR
Error raised with message "#{e}".
Backtrace would be #{e.backtrace.join('')}
EOR
end
puts check_block {"some string".sort.inspect}
puts check_block {['some', 'array'].sort.inspect}
This first block will go through and rescue with a report returned, the second will operate normally.
This rescue only rescues NoMethodError while you may need to rescue other errors.

Only run selenium test if previous selenium test fails

I have several 'it' blocks in my selenium test file (using Ruby and rspec) that test various portions of my web application. Each 'it' block stops executing and goes to the next 'it' block if any of the conditions or code fails.
Is there a way to run an 'it' block
only if the previous fails or call a
function to react to the failed test?
Is there a better way to accomplish what I am wanting to do that doesn't involve an 'it' block?
Example 'it' block
it "should load example.com" do
page.open("http://example.com")
page.wait_for_page_to_load(25)
end
I don't like my current solution and think there is a better way to accomplish this, but for now...
wrap original test code that was in the 'it' block in a begin rescue block
put code to respond to failure in the rescue section
.
it "should load example.com" do
begin
page.open("http://example.com")
page.wait_for_page_to_load(25)
"wow".should == "cool"
rescue Exception => e
// code that responds to failed test
end
end
Why I don't like this
I feel dirty writing test code like this (it feels wrong!)
The rspec reports a pass unless the rescue code also fails

Resources