# Exit call in script causes unit test to not run (newby)

**URL:** <https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720>\
**Category:** Ruby\
**Created:** [November 20, 2007, 2:05am UTC](https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720 "2007-11-20T02:05:27Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [November 20, 2007, 2:05am UTC](https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720/1 "2007-11-20T02:05:27Z")

</div>

Hello.  
I’ve been grappling with unit testing for a couple weeks now. I’m  
a bourne shell scripter by day who is trying to expand my skill  
set. I currently have a ruby script which I’m trying to create some  
unit tests for. The unit tests have not been running and I’ve  
finally traced the problem to this method. Specifically the “exit”  
call. If I comment out the exit then my tests actually run.

# Cleanup any transient files and directories and then exit

def script\_clean  
FileUtils.rm\_rf(WORKDIR) if File.exists?(WORKDIR)  
# Everything is tidy we should leave  
exit  
end

The above method is called in 2 different scenarios. The first case  
is during script execution if any Exceptions occur. Then the error  
message is printed and the script\_clean method is called to ensure the  
process exits.

Here is an example of where the method is called

```
begin
  File.open(ADMIN_FILE, "w+") {|f| f << ADMIN_CONTENTS }
rescue Exception => e
  puts e ; script_clean
end

```

Additionally if the script runs through to the end without  
encountering any errors then the last line is a call to the  
script\_clean method

script\_clean

My tests are not triggering any Exceptions so it appears to be the  
last line which calls “script\_clean” to hamper any test execution.  
Explicitly exiting when an uncorrectable error has happened is  
something I commonly do in bourne shell scripts and it made sense to  
carry over the practice in ruby. Should I be terminating premature  
and normal script execution in some other fashion that is more  
compatible with test/unit.

Here is an basic example demonstrating what I’m seeing.

------------example script to reproduce ‘exit’ call hindering unit  
tests  
require ‘optparse’

```
# Argument handling
options = {}
OptionParser.new do |o|
  o.on("-n") { |options[:noop]| }
  o.on_tail("-h", "--help", "Print usage.")
  o.parse!(ARGV)

```

end  
# Set PROTO constant based on command line arg  
if options[:noop]  
PROTO = true  
else  
PROTO = false  
end

# Example method that exits

def clean  
exit  
end

# Call clean method if PROTO is true

if PROTO  
clean  
end

----------example unit test

# Load up required supporting files

require ‘someapp’  
require ‘test/unit’

# Class to hold the config file tests

class CliTest \< Test::Unit::TestCase  
def test\_dryrun  
assert PROTO, true  
end  
end

-----------example execution where “exit” is not called  
./test\_someapp.rb  
Loaded suite ./test\_someapp  
Started  
F  
Finished in 0.013832 seconds.

1. Failure:  
test\_dryrun(CliTest) [./test\_someapp.rb:23]:  
true.  
 is not true.

1 tests, 1 assertions, 1 failures, 0 errors

----------example execution which calls “exit”  
./test\_someapp.rb -n

# echo $?

0

```
Any tips for a bourne shell convert are very much appreciated!

```

TIA. G

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [November 20, 2007, 3:23am UTC](https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720/2 "2007-11-20T03:23:44Z")

</div>

On Nov 19, 2007, at 17:05 , removed\_email\_address@domain.invalid wrote:

> If I comment out the exit then my tests actually run.
> 
> # Cleanup any transient files and directories and then exit
> 
> def script\_clean  
> FileUtils.rm\_rf(WORKDIR) if File.exists?(WORKDIR)
> 
> # Everything is tidy we should leave
> 
> exit  
> end

so don’t call exit.

really.

since it is the last thing you’re doing anyways, what is it doing for  
you? Nothing.

if you HAVE to call exit (and you don’t), then do this in your tests:

alias :old\_exit :exit  
def exit

# no

end

* * *

On second thought. Get rid of script\_clean entirely. It is useless.  
Use Tempfile instead and you’ll be happier.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [November 20, 2007, 3:45am UTC](https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720/3 "2007-11-20T03:45:22Z")

</div>

> On second thought. Get rid of script\_clean entirely. It is useless.  
> Use Tempfile instead and you’ll be happier.

Ryan.  
The script\_clean method is also used when an exception is raised not  
just as the last line of the script, if that was the case I would  
agree with your recomendation to remove it. Some of the tests I had  
planned on creating would trigger an exception to make sure my error  
handling is correct. Part of the error handling is cleaning up any  
transient files and exiting immediatly to ensure that the script does  
not continue running and do something unintended.  
If a call to “exit” impacts the execution of the unit tests I’m  
trying to understand if I should be using a different approach.  
Thanks for your suggestions!  
G.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [November 20, 2007, 7:15am UTC](https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720/4 "2007-11-20T07:15:07Z")

</div>

On Nov 19, 2007, at 18:45 , removed\_email\_address@domain.invalid wrote:

> If a call to “exit” impacts the execution of the unit tests I’m  
> trying to understand if I should be using a different approach.

A call to exit impacts the execution of ruby… not just unit tests.

I still don’t see why you need that method. Tempfile cleans up after  
itself… that is what it is for.

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [November 21, 2007, 7:50am UTC](https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720/5 "2007-11-21T07:50:55Z")

</div>

On 20.11.2007 03:43, removed\_email\_address@domain.invalid wrote:

> transient files and exiting immediatly to ensure that the script does  
> not continue running and do something unintended.

This sounds as if you did not yet get the hang of exception handling.  
If an exception is so serious that the whole program cannot possibly  
proceed then don’t catch the exception (or catch and rethrow another  
one). There are a lot mechanisms to ensure proper and robust cleanup,  
e.g. “ensure” clauses, END, at\_exit, ObjectSpace.define\_finalizer and on  
a higher level as Ryan pointed out: Tempfile, File.open with block …

> If a call to “exit” impacts the execution of the unit tests I’m  
> trying to understand if I should be using a different approach.

Yes, IMHO you should use a different approach - but not only to testing  
but as well (and more important) to error handling. Please try to get  
rid of your shell mindset when doing Ruby development.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [November 20, 2007, 10:49am UTC](https://www.ruby-forum.com/t/exit-call-in-script-causes-unit-test-to-not-run-newby/120720/6 "2007-11-20T10:49:52Z")

</div>

2007/11/20, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> FileUtils.rm_rf(WORKDIR) if File.exists?(WORKDIR)
> 
> ```
> 
> script\_clean
> 
> My tests are not triggering any Exceptions so it appears to be the  
> last line which calls “script\_clean” to hamper any test execution.  
> Explicitly exiting when an uncorrectable error has happened is  
> something I commonly do in bourne shell scripts and it made sense to  
> carry over the practice in ruby.

I disagree. Ruby and Bourne Shell are two completely different  
languages. Especially shell does not have exception handling. I  
would especially not exit from unit tests but raise an exception.  
Even if you use exit you can make sure your cleanup code is run by  
placing it in END or a global “ensure” clause:

10:46:02 /cygdrive/c/SCMws/RKlemme/OPSC\_Gold\_bas\_dev\_R1.1.5\_s11\_pp/bas  
$ ruby -e ‘END{puts 1}; exit 2’  
1  
10:46:05 /cygdrive/c/SCMws/RKlemme/OPSC\_Gold\_bas\_dev\_R1.1.5\_s11\_pp/bas  
$ ruby -e ‘begin; exit 2;ensure puts 1; end’  
1

> Should I be terminating premature  
> and normal script execution in some other fashion that is more  
> compatible with test/unit.

Yes, raise an exception. Btw, exit does actually throw an exception  
but maybe that’s not caught by the test framework.

$ ruby -e ‘begin; exit 2; rescue Exception =\> e; p e, e.class,  
e.class.ancestors; end’  
#\<SystemExit: exit\>  
SystemExit  
[SystemExit, Exception, Object, Kernel]

You usually do not want your complete test suite to terminate when a  
single test fails.

Kind regards

robert
