assert_equal is better than eyes for testing

Once again I understood why testing properly is important when I came up with an interesting problem yesterday night. I am writing a ruby program to download flash videos from sites like Youtube, Blip.tv, Metacafe… to watch them while I am offline. I have a text file. On its first line I wrote the path to the directory to store them and URLs of videos on the next lines. The content of it looks like:

c:/temp/download

http://www.youtube.com/watch?v=QZnyrp__CNU

http://www.youtube.com/watch?v=_x0YtFUYSvY

http://www.youtube.com/watch?v=_sM9vcAIYyc

…….

So, here is my plan: read the lines from file into an array, create the download directory and grab the videos to that folder. To read the lines and create the folder, I did:

lines = IO.readlines(‘c:/temp/config.txt’)

dir = lines[0]

FileUtils.make_p(dir)

When I ran that, it produced:

  1) Error:
test_initialize(TestYoutubexDownloader):
Errno::EINVAL: Invalid argument – c:/temp/download

    …..
    C:/ruby/lib/ruby/1.8/fileutils.rb:201:in `each’
    C:/ruby/lib/ruby/1.8/fileutils.rb:201:in `mkdir_p’
    C:/temp/Youtubex/test/TestYoutubexDownloader.rb:23:in `test_initialize

1 tests, 0 assertions, 0 failures, 1 errors

Very simple code, but FileUtils didn’t behave as expected. So I changed the code to:

lines = IO.readlines(‘c:/temp/config.txt’)

dir = lines[0]

# FileUtils.make_p(dir)

FileUtils.make_p(“c:/temp/download”)

This time it worked and folder is created. So I thought IO.readlines is not getting lines from file and dir is not correctly initiated. To see it ,I did:

lines = IO.readlines(‘c:/temp/config.txt’)

dir = lines[0]

puts “directory=” + dir

FileUtils.make_p(dir)

# FileUtils.make_p(“c:/temp/download”)

So when I executed the code, output is as follows:

Started
directory=c:/temp/download
E
Finished in 0.0 seconds.

  1) Error:
test_initialize(TestYoutubexDownloader):
Errno::EINVAL: Invalid argument – c:/temp/download

     …….
    C:/ruby/lib/ruby/1.8/fileutils.rb:201:in `each’
    C:/ruby/lib/ruby/1.8/fileutils.rb:201:in `mkdir_p’
    C:/temp/Youtubex/test/TestYoutubexDownloader.rb:25:in `test_initialize’

The directory path is correct since I see it on the debug output of my computer screen but still FileUtils.make_p is not doing the right thing. I passed the string manually it worked but when passed through a parameter with the correct value, the error occurs. So what maybe the problem??? :) Then I decided to make a check with assert_equal instead of puts statement. I knew that it will act same, since I saw the output on screen but did it:

lines = IO.readlines(‘c:/temp/config.txt’)

dir = lines[0]

assert_equal(“c:/temp/download”, dir)

And it produced:

  1) Failure:
test_initialize(TestYoutubexDownloader) [C:/temp/Youtubex/test/TestYoutubexDownloader.rb:24]:
<”c:/temp/download”> expected but was
<”c:/temp/download\n”>.

The trick is when the line is fetched by IO.readlines, newline characters at the end are also preserved. Eyes doesn’t detect newline characters so this type of testing doesn’t help. So they must be stripped if we want to clear them:

lines = IO.readlines(‘c:/temp/config.txt’).collect!{|line| line.strip}

dir = lines[0]

FileUtils.make_p(dir)

At last it worked :) I lost time by making guesses for the problem but the solution was simple, do the assertion test at the first time instead of making guesses or fighting with the debug output strings! The results of the puts, writeln, printf.. statements may lead us to a wrong way during testing and they must be avoided as becoming the first choice to use when tension is high in projects. Furthermore; not only for Ruby but xUnit testing tools are available for most of the other languages and testing with them is much more fun than the old debug methods!

Leave a Comment