When We Build

Awesome presentation from Wilson Miner at Buildconf. Perfect.


Writing Testable Code

In the last few years, several types of development have emerged: Test Driven Development, Behavior Driven Development and others. At the same time I see the benefits of what is stated by their creators, I don’t think that writing tests or specifying behavior upfront always a good thing for all kinds of projects. In fact, I suspect it isn’t even possible for some projects, due its natures.

Please beware I’m not discouraging you to use those methodologies in any way. My objective with this essay is to encourage you as developer to write as much testable code as possible.

What Testable Code Is?

We should start with the modern definition of code, according to Wikipedia:

In computer science, source code is a text written using the format and syntax of the programming language, or a computer language of another purpose, that it is being written in.

Basically, it is the text written in some language, defining a set of instructions, that will be transformed at some point into computer commands and executed by the computer.

For the computer, it really doesn’t matter how we write the code, as long it makes sense at the time it executes. Simple like that.

Several programing paradigms were created since the beginning of computing: procedural, functional, object oriented programming, amongst other more obscure. As I mentioned before, the net result of each one of these programming paradigms is to produce computer executable code, and it is possible that programs written in languages implementing different paradigms produce the exact same computer executable code.

What I call testable code is the code you, as developer, write and have enough hooks to enable it to be tested when necessary. For instance, take in account the following piece of Python code:

def read_input_file():
    file('/tmp/input_file.txt').readlines()

This code will be interpreted and transformed correctly and does what we want: it opens the right input file, and read its contents. Now, what if we want to test the behavior of our application with a different input file? One could, quickly, change the code:

def read_input_file():
    file('/tmp/test_input_file.txt').readlines()

This represents a chunk of code that isn’t testable. By doing a simple modification to our function, we can turn it into a piece of testable code:

def read_input_file(input_file_path="/tmp/input_file.txt"):
    file(input_file_path).readlines()

Writing Testable Code

Of course, the example above is quite simple and doesn’t represent the whole class of cases we can find. At work once I found a class method that returned, aided by several heuristics, a database table name. This class method was quite important, since it was used by several other methods within that class to perform all sorts of operations. The problem was that there were no easy way to override the heuristics to use a test database table. The solution was to use brute force: overwrite the method to return the table name I wanted. If I had to write a Python version of the original class, it’d be something like the following:

class MyClass:
    # ...
    def table_name(self):
        table_name = ... # use some heuristics to calculate the table name.
        return table_name

To transform it to a testable piece of code, I’d do like the following:

class MyClass:
    _table_name = None
    # ...
    def table_name(self):
        table_name = self._table_name
        if not table_name:
            table_name = ... # use some heuristics to calculate the table name.
        return table_name

We could test the code like this:

>>> obj = MyClass()
>>> obj._table_name = 'Bar'
>>> obj.table_name()
'Bar'
>>> obj = MyClass()
>>> obj.table_name()
'Foo'

Some other programming languages are more structured, with practices that allow code to be tested more easily. One example is the Cocoa framework, which makes extensive use of the Delegation Pattern, where a piece of code delegates the responsibility of certain aspects of the code path to a delegate object. This approach makes the code more testable.

Below you can see a delegate protocol definition:

@protocol MyClassDelegate

- (void)myClassDidFinishLoading:(id)obj;
- (void)myClass:(id)obj didFailWithError:(NSError *)error;

@end

And now, the implementation of a class that uses the MyClassDelegate shown above:

@interface MyClass

@property (nonatomic, weak) id<MyClassDelegate> delegate;

- (void)doSomething;

@end

@implementation MyClass

@synthesize delegate;

- (void)doSomething;
{
    BOOL success = NO;
    NSError *error = nil;
    // Do something important here, and update the ‘success’ variable. If an error
    // occurs, the error description will be stored in the ‘error’ variable.

    if (success)
        [self.delegate myClassDidFinishLoading:self];
    else
        [self.delegate myClass:self didFailWithError:error];
}

@end

We know that when the -doSomething message is sent to an MyClass instance, it’ll send either the -myClassDidFinishLoading: or -myClass:didFailWithError: messages to the delegate instance. If we want to test the code written above, it’d be as simple as this:

@interface MyTestDelegate : NSObject <MyClassDelegate>

@end

@implementation MyTestDelegate

- (void)myClassDidFinishLoading:(id)obj;
{
    NSLog(@"SUCCESS");
}

- (void)myClass:(id)obj didFailWithError:(NSError *)error;
{
    NSLog(@"FAIL: %@", error);
}

@end

And somewhere in your test case:

// Create a MyClass class instance.
MyClass *obj = [[MyClass alloc] init];

// Create our test delegate object.
MyTestDelegate *testDelegate = [[MyTestDelegate alloc] init];

// Assign our MyClass instance’s delegate to our test delegate object.
obj.delegate = testDelegate;

// Send a message to obj and expect to read either “SUCCESS” or “FAIL” in
// the application’s log.
[obj doSomething];

Conclusion

Some programming languages have this testability aspect built in its core, making it easier to write code that’s easy to test when required, but the majority of the programming languages require a good deal of discipline and organization from the developer’s side.

Although the Delegation Pattern is one of the signature patterns in Objective-C, nothing stops you to design software using this pattern, or even the Inversion of Control Pattern in projects using Python, Ruby or even Perl.


Gidsy

I discovered Gidsy while booking for the blog workshop I attended last week and I immediately fell in love with it, for several reasons.

Beautiful Design

Gidsy’s design has a tremendous good taste. The color palette is well chosen and is really easy on the eyes.

The chosen types are spot on as well:

  • Myriad Pro Semi Condensed used in the headers; and
  • Myriad Pro used in the text and UI controls.

Another great example on good taste are the colorful icons, which are present everywhere in the website. Simple and well designed, it is an example for the “one image is worth a thousand words” motto.

Great Usability

It is simple to use. Really simple. Kudos to Andrew McCarthy for having designed this delightful web site. I can see a lot of effort put on details that will remain unseen by the majority of users, such as the mouse-over transition from the “Gidsy” logo to “Home”.

Awesome!

Awesome Idea

Other than the extreme good taste and an example of well designed website, it is an example of modern and thoughtful implementation of a concept. Its creators aim to enable normal people like you and me to host exciting activities such as workshops and tours. It is basically the idea of think locally and act globally.

There are several examples of those interesting activities already being hosted there, such as Making fresh Pasta di Mama with AH food[1] and Amsterdam Sightrunning.

In fact, I found the idea so amazing that I’m thinking about host my own workshop, but I still don’t know the subject.

I think you also should consider doing it, because in life you’re either learning or teaching. And everybody have something to teach.


  1. AH stands for Albert Heijn, which is a dutch supermarket chain. This serves pretty much as example for the local thinking I mentioned before.


Blog Workshop

Last week I attended a Blog workshop hosted by the blogger and author Ernst-Jan Pfauth of Dutch Pro Blogger and Sex, Blogs & Rock’n Roll fame.

During three hours, myself and a group of other 14 people–with several different backgrounds, including journalists and computer developers–listened carefully about the blogging world, trying to absorb as much as possible all the knowledge provided by Ernst-Jan.

I still need to digest most of the information given by Ernst-Jan at the workshop, but some ideas started to grow on my head. And this post is part of it.


Follow

Get every new post delivered to your Inbox.