|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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", "--", "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. <false> 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 |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Nov 19, 2007, at 17:05 , weathercoach@gmail.com 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 ld_exit :exitdef exit # no end --- On second thought. Get rid of script_clean entirely. It is useless. Use Tempfile instead and you'll be happier. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
>
> 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. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Nov 19, 2007, at 18:45 , weathercoach@gmail.com 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. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
2007/11/20, weathercoach@gmail.com <weathercoach@gmail.com>:
> 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. 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 -- use.inject do |as, often| as.you_can - without end |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On 20.11.2007 03:43, weathercoach@gmail.com wrote:
>> 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. 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 |
|
![]() |
| Outils de la discussion | |
|
|