Need some help

Hi,

I have a script in one file say "a.rb".
I have another file "tc_a.rb" which is a test case for "a.rb"
I have called a specific script in "a.rb" by using the system() command from
"tc_a.rb"

Now when i am using rcov to get the code coverage, although an if -else
block in "a.rb" is getting executed, rcov doesn't seem to recognise it... it
still shows the block as not covered...May be because it is getting called
through the system command

This particular if-else block is an independent one i.e. not present in any
method in "a.rb"

I need to get this block covered...

Can someone suggest a solution?

Thanks
Disha

Are you doing something like, taking arguments

e.g:

ARGV[0].do_something

and you want to test this?

if that's the case, split it up into a library / script combo, and
make the functions testable

···

On 5/21/07, Disha Tamhane <disha.tamhane@gmail.com> wrote:

Hi,

I have a script in one file say "a.rb".
I have another file "tc_a.rb" which is a test case for "a.rb"
I have called a specific script in "a.rb" by using the system() command from
"tc_a.rb"

Now when i am using rcov to get the code coverage, although an if -else
block in "a.rb" is getting executed, rcov doesn't seem to recognise it... it
still shows the block as not covered...May be because it is getting called
through the system command

This particular if-else block is an independent one i.e. not present in any
method in "a.rb"

I need to get this block covered...

Can someone suggest a solution?

#---------

def do_it(arg)
  arg.do_something
end

if __FILE__ == $PROGRAM_NAME
  do_it(ARGV[0])
end

#------

Now you can test the do_it method by just requiring the file.
if you do this cleanly enough, there won't be much left to test in your script.

Hey Gregory,

Thanks for your response.

Following is the code snippet that i am trying to test :

basedir = ARGV[0]

if (ARGV[0])
    contains = Dir.new(basedir).entries
    for file in contains
        if (file != "." && file !="..")
            tokens = file.split("-");
            model = tokens[0]
            tokens1 = tokens[2].split(".xm")
            dealer = tokens1[0]
            puts model + "," + dealer + "," + basedir + "/" + file
            getallocprsr = GetAllocationsParser.new
            getallocprsr.parsefile(basedir + "/" + file)
            sql = "UPDATE Validations set getAlloc = " +
getallocprsr.allocation.to_s
            sql = sql + " where DealerName like '" + dealer + "' and
Vehicleline like '" + model + "'"
            puts sql
            db.updateQuery(sql)
        end
    end
else

    puts "Usage :"
    puts ""
    puts "$> ruby a.rb <basedir> "
    puts ""
    puts "basedir : This is the base directory where the getAllocations
responses"
    puts " can be found"
    puts ""
end
db.close

Thanks,

Disha

···

On 5/21/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

On 5/21/07, Disha Tamhane <disha.tamhane@gmail.com> wrote:
> Hi,
>
> I have a script in one file say "a.rb".
> I have another file "tc_a.rb" which is a test case for "a.rb"
> I have called a specific script in "a.rb" by using the system() command
from
> "tc_a.rb"
>
> Now when i am using rcov to get the code coverage, although an if -else
> block in "a.rb" is getting executed, rcov doesn't seem to recognise
it... it
> still shows the block as not covered...May be because it is getting
called
> through the system command
>
> This particular if-else block is an independent one i.e. not present in
any
> method in "a.rb"
>
> I need to get this block covered...
>
> Can someone suggest a solution?

Are you doing something like, taking arguments

e.g:

ARGV[0].do_something

and you want to test this?

if that's the case, split it up into a library / script combo, and
make the functions testable

#---------

def do_it(arg)
arg.do_something
end

if __FILE__ == $PROGRAM_NAME
do_it(ARGV[0])
end

#------

Now you can test the do_it method by just requiring the file.
if you do this cleanly enough, there won't be much left to test in your
script.

Hey Gregory,

Thanks for your response.

Following is the code snippet that i am trying to test :

basedir = ARGV[0]

Wrap the code below in a method like this:

def do_something_with_basedir(dir)
#...
end

and pass it the values you want to test in your unit tests.

if (ARGV[0])
    contains = Dir.new(basedir).entries
    for file in contains
        if (file != "." && file !="..")
            tokens = file.split("-");
            model = tokens[0]
            tokens1 = tokens[2].split(".xm")
            dealer = tokens1[0]
            puts model + "," + dealer + "," + basedir + "/" + file
            getallocprsr = GetAllocationsParser.new
            getallocprsr.parsefile(basedir + "/" + file)
            sql = "UPDATE Validations set getAlloc = " +
getallocprsr.allocation.to_s
            sql = sql + " where DealerName like '" + dealer + "' and
Vehicleline like '" + model + "'"
            puts sql
            db.updateQuery(sql)
        end
    end
else

    puts "Usage :"
    puts ""
    puts "$> ruby a.rb <basedir> "
    puts ""
    puts "basedir : This is the base directory where the getAllocations
responses"
    puts " can be found"
    puts ""
end
db.close

If you want to test this text output, have a look at the StringIO docs

···

On 5/21/07, Disha Tamhane <disha.tamhane@gmail.com> wrote:

Gregory is right - you should put ARGV handling somewhere aside to
make testing easier.

That said, you can pass arguments to your script using -- delimiter,
but IMO they should be test harness related, not code-under-test
related. For example,
rcov -replace-progname [i.e. rcov option] tc_xxx.rb -- -whatever a b
[script options]

rcov normally changes $0 as well, so I use to add --replace-progname
and use this version of if __FILE__ == $0 guard:

if File.expand_path(__FILE__) == File.expand_path($0)
....
end

(it fixes the $0 == 'script.rb' vs. $0 == './script.rb' case)

J.

···

On 5/21/07, Disha Tamhane <disha.tamhane@gmail.com> wrote:

Hey Gregory,

Thanks for your response.

Following is the code snippet that i am trying to test :

basedir = ARGV[0]

if (ARGV[0])
    contains = Dir.new(basedir).entries
    for file in contains
        if (file != "." && file !="..")
            tokens = file.split("-");
            model = tokens[0]
            tokens1 = tokens[2].split(".xm")
            dealer = tokens1[0]
            puts model + "," + dealer + "," + basedir + "/" + file
            getallocprsr = GetAllocationsParser.new
            getallocprsr.parsefile(basedir + "/" + file)
            sql = "UPDATE Validations set getAlloc = " +
getallocprsr.allocation.to_s
            sql = sql + " where DealerName like '" + dealer + "' and
Vehicleline like '" + model + "'"
            puts sql
            db.updateQuery(sql)
        end
    end
else

    puts "Usage :"
    puts ""
    puts "$> ruby a.rb <basedir> "
    puts ""
    puts "basedir : This is the base directory where the getAllocations
responses"
    puts " can be found"
    puts ""
end
db.close

Thanks,

Disha

On 5/21/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:
>
> On 5/21/07, Disha Tamhane <disha.tamhane@gmail.com> wrote:
> > Hi,
> >
> > I have a script in one file say "a.rb".
> > I have another file "tc_a.rb" which is a test case for "a.rb"
> > I have called a specific script in "a.rb" by using the system() command
> from
> > "tc_a.rb"
> >
> > Now when i am using rcov to get the code coverage, although an if -else
> > block in "a.rb" is getting executed, rcov doesn't seem to recognise
> it... it
> > still shows the block as not covered...May be because it is getting
> called
> > through the system command
> >
> > This particular if-else block is an independent one i.e. not present in
> any
> > method in "a.rb"
> >
> > I need to get this block covered...
> >
> > Can someone suggest a solution?
>
> Are you doing something like, taking arguments
>
> e.g:
>
> ARGV[0].do_something
>
> and you want to test this?
>
> if that's the case, split it up into a library / script combo, and
> make the functions testable
>
> #---------
>
> def do_it(arg)
> arg.do_something
> end
>
> if __FILE__ == $PROGRAM_NAME
> do_it(ARGV[0])
> end
>
> #------
>
> Now you can test the do_it method by just requiring the file.
> if you do this cleanly enough, there won't be much left to test in your
> script.

Thanks Gregory.... Guess this will work now...

But just to check.. will it not work if it is not enclosed in a method?

Is there an alternative way?

···

On 5/21/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

On 5/21/07, Disha Tamhane <disha.tamhane@gmail.com> wrote:
> Hey Gregory,
>
> Thanks for your response.
>
> Following is the code snippet that i am trying to test :
>
> basedir = ARGV[0]

Wrap the code below in a method like this:

def do_something_with_basedir(dir)
#...
end

and pass it the values you want to test in your unit tests.

> if (ARGV[0])
> contains = Dir.new(basedir).entries
> for file in contains
> if (file != "." && file !="..")
> tokens = file.split("-");
> model = tokens[0]
> tokens1 = tokens[2].split(".xm")
> dealer = tokens1[0]
> puts model + "," + dealer + "," + basedir + "/" + file
> getallocprsr = GetAllocationsParser.new
> getallocprsr.parsefile(basedir + "/" + file)
> sql = "UPDATE Validations set getAlloc = " +
> getallocprsr.allocation.to_s
> sql = sql + " where DealerName like '" + dealer + "' and
> Vehicleline like '" + model + "'"
> puts sql
> db.updateQuery(sql)
> end
> end
> else
>
> puts "Usage :"
> puts ""
> puts "$> ruby a.rb <basedir> "
> puts ""
> puts "basedir : This is the base directory where the getAllocations
> responses"
> puts " can be found"
> puts ""
> end
> db.close

If you want to test this text output, have a look at the StringIO docs

Usually you will want to structure your code so it is most easily
testable. For example, if you were using system() because you wanted
to test the output to the screen, you can still test that.

Here's a small example

def hello(out=STDOUT)
  out.puts "Hello World"
end

If you were to call that, just as hello(), it'd print to the screen.

But say you wanted to test it, you could use StringIO.

···

On 5/21/07, Disha Tamhane <disha.tamhane@gmail.com> wrote:

Thanks Gregory.... Guess this will work now...

But just to check.. will it not work if it is not enclosed in a method?

Is there an alternative way?

#------
require "stringio"
require "test/unit"

class HelloTest < Test::Unit::TestCase
  def test_hello
    out = StringIO.new
    hello(out)
    out.rewind
    assert_equal "Hello World\n", out.read
  end
end
#----

In general, this makes your code more well organized and easier to
work with. If you want to do good testing, it pretty much means
you'll need to structure your code so it can be tested :slight_smile: