Re.Mark

My Life As A Blog

Archive for the ‘Unit Testing’ Category

Ruby Tuesday #15 : Ruby Round Up

leave a comment »

There’s a few things I’ve noticed over the last week in the Rubyverse that I thought it was worth highligting.  In no particular order, here we go.

In my Ruby doodlings, I’ve spent quite a bit of time with REXML.  GIven that I’m focussed on learning Ruby rather than deploying code, there’s no issue.  However, this post from RubyInside shows there are alternatives such as libxml-ruby.

Testing, both TDD and BDD style, are prominent in the Ruby community.  This post examines the reasons to unit test, questions the emphasis placed on unit testing and highlights the importance of remembering why you test.  Well worth reading and relevant regardless of your preferred language.

Finally, I came across a couple of resources that those who, like me, are learning Ruby may find valuable.  The first is the news that there is a new chapter in the Book of Ruby.  The second is a couple of posts about learning Ruby for C#ers.  These posts also mention IronRuby, so well worth reading.

Written by remark

July 23, 2008 at 6:33 am

Ruby Tuesday #13 : Testing

with one comment

Having completed a rudimentary Twitter client, I thought it was high time I figured out how unit testing works in Ruby.  The good news is that there’s a framework (called Test::Unit) distributed with Ruby.  To create a class of tests, simply create a new class and inherit from Test::Unit::TestCase.  Any method in the class that begin with test will be executed as tests.  Here’s a simple test for the translator in my Twitter client:

require 'test/unit'
require 'Twitter'
require 'rexml/document'

include REXML

class Test_Translator < Test::Unit::TestCase

    def test_element_to_user
        xml = '<user>
        <id>99999999</id>
        <name>Username</name>
        <screen_name>Screen Name</screen_name>
        <location>Location</location>
        <description>Description</description>
        <profile_image_url>image_url</profile_image_url>
        <url>url</url>
        <protected>false</protected>
        <followers_count>404</followers_count>
        </user>'
        translator = Translator.new
        element = get_user_element(xml)
        user = translator.element_to_user(element)
        assert_equal('99999999', user.id)
        assert_equal('Username', user.name)
        assert_equal('Screen Name', user.screen_name)
        assert_equal('Location', user.location)
        assert_equal('Description', user.description)
        assert_equal('image_url', user.image_url)
        assert_equal('url', user.url)
        assert_equal('false', user.protected)
        assert_equal('404', user.followers_count)
    end

    private

    def get_user_element(xml)
        xml_document = Document.new(xml)
        xml_document.root
    end
end

Run that test and it tells me there are 8 assertions in 1 test.  And there’s an error.  The error is a NoMethodError – tells me that there is no method followers_count on the User instance.  And looking at the class it’s clear why:

class User
    attr_reader :id, :name, :screen_name, :location, :description, :image_url, :url, :protected

    def initialize(id, name, screen_name, location, description, image_url, url, protected, followers_count)
        @id = id
        @name = name
        @screen_name = screen_name
        @location = location
        @description = description
        @image_url = image_url
        @url = url
        @protected = protected
        @followers_count = followers_count
    end
end

There’s an instance variable that gets set when an instance is created, but there’s no property defined.  All that’s needed is to update the first line of the class like so:

attr_reader :id, :name, :screen_name, :location, :description, :image_url, :url, :protected, :followers_count

And the test passes.  Lots more to learn in Test::Unit, but that feels like a good start.

When I started this series of Ruby Tuesdays, Matt recommended ZenTest, so I thought I’d look at that, too.  You can install it as a gem.  Once it’s installed, I called it with the following command:

zentest Twitter.rb >Test_Twitter.rb

That creates a file called Test_Twitter.rb that contains tests for the methods in Twitter.rb.  Here’s a brief excerpt:

class TestClient < Test::Unit::TestCase
    def test_download_friends_timeline
        raise NotImplementedError, 'Need to write test_download_friends_timeline'
    end

As you can see, for each method an error is raised to prompt you to write the test code.  There’s some other goodness in there like the autotest daemon that automatically runs your tests as you make changes.  And if you like to have your tests running automatically and you use Growlthis might be for you.

Written by remark

July 8, 2008 at 7:05 pm

Test Driven Debate

with 3 comments

I ran into this post the other day.  You’ve got to agree that’s an eye catching title for a blog post.  Reading a title like that you might expect an anti unit testing rant, whereas it actually makes the case for a pragmatic approach at the heart of which is testing.  And that’s important – the focus should be on delivering working software, not on making sure you’re doing a before b.I see a lot of value in unit testing and high unit test coverage – I think it encourages better design along with more confidence in the code base (although I’d like to see more capability a la Eiffel built into languages, which would allows us to junk a bunch of the grunt tests and would make the intention of the code clearer.)  I’m less sure about TDD. There’s no doubt it has its passionate followers, but the focus on the how may be at the expense of the why, and that’s a niggling doubt.

Written by remark

March 11, 2008 at 11:01 pm

Testing changes

leave a comment »

As you start to adopt unit testing, you’ll notice that you start to design your code differently.  Being able to test your code thoroughly becomes the imperative.  And, maybe counter-intuitively, that imperative promotes good design.  Some of that good design may not be what you thought was good design before.  This post, by Tim Ottinger, is an excellent description of the changes you’ll observe.

Written by remark

July 18, 2007 at 8:31 pm

Executable XML

with one comment

Earlier I posted about Synapse.  My biggest concern about Synapse is that there is a lot of XML to write.  To be fair, this is hardly a unique characteristic of Synapse.  nspectre is primarily configured in XML – although you can write your own implementation of IConfigurationReader if you prefer something else.   With the advent of .NET 3.0 XAML is a development that can’t be ignored.

So, all this XML is a great thing, right?  Er, well, no.  I don’t think so.  In a lot of cases, we are using XML as the basis of a DSL – which means that the XML is code.  And that means it gets executed.  And here’s the issue – how do you test all that code?  The unit testing support that is standard fare in most modern languages is absent in this space.  We know what happens when you don’t unit test.  And this gets even worse when the XML is generated by a tool, because in addition to the unit testing issue, it can become difficult to diff – which makes bug detection even harder.  (I should just add a quick note about nspectre here.  Since it generates code at runtime for use by .NET code, it is relatively straightforward to unit test the logic expressed in the configuration – which means you can write unit tests that express the intent and if you change the config in a way that breaks the tests then you know you have a problem.)

I also get the feeling that sometimes XML is being used to add a dynamic capability to static languages.  If that is the case, then shouldn’t we be using languages that have the features we want?

I like flexibility as much as the next person, but I’m concerned about anything that is a block to change.  And executable XML often falls into this category.  Proceed with caution.

Written by remark

June 23, 2007 at 1:28 pm

You don’t want to do it like that

leave a comment »

James Carr has compiled a useful list of TDD Anti Patterns.  Worth reading.  And if you want to read more about unit testing, may I recommend Michael Feather’s book, Working Effectively with Legacy Code?  This is a great book that describes refactoring techniques you can apply to apply unit testing to existing, untested code – the sort of code that often feels untestable.  After reading this book I felt that in addition to being able to tackle legacy code, I had a much more instinctive feel for how to design code to be testable.  James’ post helps to keep the tests you’re writing clean.

Written by remark

December 7, 2006 at 10:22 pm

Posted in Unit Testing

Ghosts in the machine

leave a comment »

On Roy Osherove’s blog, I found this post about NSpec. Obviously, the name piqued my interest. It (NSpec – and also Specter, which is mentioned in the comments) seems to be addressing a different part of the development cycle compared to nspectre. Whereas nspectre is a run-time framework for business logic (or behaviour) in the form of specifications, NSpec focuses on test time. Specifications written in nspectre are easy to test – but maybe a compelling extension to nspectre would be auto-generation of tests of the specifications or something along those lines.

Written by remark

July 3, 2006 at 2:00 pm

Limits to Independence

leave a comment »

The solution I described yesterday has a drawback – it increases the scope of the created class. This may be acceptable – it may even be desirable – in some instances, but there are situations where you have to think of something else. In the case of nspectre, a reference ValidatorFactory needs to held for the lifetime of an application because it compiles the specifications once when they are first required. So, if we were to hold references at class level in ValidatorFactory, they would never be eligible for garbage collection.
Let's say we have a class called, uninspiringly, Foo that creates an instance of class called – you guessed correctly – Bar. One solution is to create a protected method in Foo that returns a new instance of Bar. In our unit tests we subclass Foo and override the newly created protected method. Then we can either extract the interface from Bar and make Bar implement this interface (IBar) and mock Bar in the unit tests. It would also be possible to return a fake Bar – maybe by subclassing Bar.

Written by remark

April 26, 2006 at 8:05 pm

More Independence

leave a comment »

Having put in a few logging messages into nspectre to prove the principle, it's time to test the logging messages. Given that the design relies on an ILogger interface, this is fairly easy with mocks. What I noticed fairly quickly was a class that created another class – which meant that testing logging would mean testing it in more than the target class.
The solution is to extract an interface from the class being created by the target class and pass it to the target class in the constructor. Now I can also mock the class that was being created. In this instance, the code that results is more elegant. All tests have been updated and they all pass. Once more the tests have proven their worth – this kind of refactoring would have been scary without them.

Written by remark

April 25, 2006 at 10:57 pm

Follow

Get every new post delivered to your Inbox.