Archive for March, 2011

We don’t have time for tests

Saturday, March 26th, 2011

At lunch I had the familiar conversation about how TDD/pairing are fine unless you’re under pressure to deliver, and then …. you just do whatever it takes. Well, if you don’t think TDD/pairing are “what it takes,” then why do you /ever/ work that way?
Dave Nicolette

Same thing here. I was talking with a potential customer the other day and he said “for most projects here we don’t have time to write tests, we just code like hell to get them finished as soon as we can”. Well, but writing tests, for me, *is* the way to get it finished as soon as I can. The moment when we’re under pressure is the moment we should stick to good technique the most.

One example of this is a nice coding competition by Lasse Koskela and Markus Hjort at XP Days Benelux 2006. The objective of the game was to write a program to play Indian Poker (a silly, fun version of Poker) and win against other programs. The whole competition lasted less than three hours. As you can imagine there was not much time to waste :-) So what did we do? (I was pairing with a young chap from Philips who didn’t know much Java, so I, well, kept the keyboard all the time.) As I mentioned in my earlier report on the event, We wrote an acceptance test and then we used TDD. We did drive *all* code with tests. And we won :-)

How did we win? Well, for one thing, half the other programs crashed. Ours didn’t. We decided on a simple strategy to decide when to “stay” and when to “fold”. Since we finished early and we still had something like 10 minutes, we decided to add an option of raising if the cards looked very good for us. Still driving code with tests. And you know what? At the last round only two or three programs remained. Our bot won by raising!

Three hours, a new API, a new problem. I did what it takes: to use the best programming technique I know. I don’t have time for working in a sloppy way.

David Tchepak on TDD

Friday, March 25th, 2011

David Tchepak wrote a thoughtful post on TDD. I share what he says. I find useful this little summary:

The process of writing the test gives us all sorts of feedback.

  • The setup is too long or complicated? We’ve probably got too many collaborators (or are violating the Law of Demeter for them) and can try encapsulating them behind a new abstraction.
  • Too many scenarios or test fixtures on the same SUT? Our SUT probably has too many responsibilities.
  • Too hard to isolate the behaviour we’re trying to test, or can’t find how to write an assert for the behaviour? Maybe the current API or abstraction is wrong, and needs to be broken down differently?

[…] Writing the test first gives us ample opportunity to respond to this feedback, to sketch out our design, before committing to it. There is no cheaper time to change your code than before it is written.

The article is full of little gems like this note:

If you can’t get TDD to help you with a problem, make a note of it before trying something else, and come back to it later. It is important to see if it was just a problem TDD was ill-suited for, or whether a gap in your knowledge has been exposed. You’ll never know the difference if you give up too easily on TDD. Pursuing these leads is what led me to discover mocking, IoC containers, conventions, BDD etc. And I’m far from finished finding gaps in my knowledge. ;)

I like this tone. He does admit that TDD will not always for us, yet he advises not to accept that as a fact. Every obstacle in our work should be a reason to sit down and think what we could have done differently. Just as a team should not accept bugs as an inevitable fact of life, but should treat each one as an indication that they must do something to improve their process, the same should apply to when we are “stuck” not knowing how to proceed, or when we don’t like how our code turned out to be. Think about it; what part in our process could have been improved so that this does not happen again? (And if this leads me to think “my process? what process??”, great! I’m on the right path to improve :-)

Algebraic datatypes in Java

Thursday, March 10th, 2011

Being in bed with a little fever, I thought it might be a good time for a little easy work on functional programming in Java.

Haskell envy

One of the things functional programmers often use is algebraic datatypes. For instance, in Haskell you would define a binary tree as such:

type tree = Empty
          | Leaf of int
          | Node of tree * tree
  

This says that a tree is either the Empty tree, or a Leaf that carries an integer value, or a Node that carries two subtrees.

The next thing is to define functions, such as tree height; the nice thing is that the functions are then defined by cases. It’s kind of fun:

height :: Tree -> Int
height Empty = 0
height (Leaf n) = 1
height (Node l r) = 1 + max (height l) (height r)    
  

This says that an Empty tree has height 0, a Leaf has height 1, and a Node has height that is the maximum height of its subtrees, plus 1. Now we could have fun defining all sorts of other functions, like the contour (the list of the integers of all leafs), search for a particular value, addition of elements, and so on.

Additionally, when working in languages like Haskell, the compiler makes sure that when we define a function by cases, the program will not compile unless we remembered to define all cases.

This sort of data structures have all sort of applications; an obvious one is representing syntax trees, that is the output of a parser. Another one is representing the syntax rules themselves.

We can do it!

What’s to do if you have to work in a simpler language like Java? Do we have to give up the fun of algebraic data types? Of course not! It’s possible to define such structures in Java, even though it will take one or two orders of magnitude more lines of code.

Step zero: define the structure

public abstract class Tree {}

public class EmptyTree extends Tree {}

public class Leaf extends Tree {
    public Leaf(int value) {
    }
}

public class Node extends Tree {
    public Node(Tree left, Tree right) {
    }
}    

Now we can create our trees with the following deliciously clumsy syntax:

Tree tree = new Node(
    new Node(new Leaf(0), new EmptyTree()), 
    new EmptyTree());    

We could make it slightly less verbose with static functions.

Step one: define height

The easy way to add a function is to define it abstractly in Tree. The compiler then forces us to define it in all Tree subclasses (in all cases). First a test:

@Test
public void heightOfSimpleTree() throws Exception {     
    Tree tree = new Node(
        new Node(new Leaf(0), new EmptyTree()),
        new EmptyTree());
    assertEquals(3, tree.height());
}

Then the implementation:

public abstract class Tree {
    public abstract int height();
}


public class EmptyTree extends Tree {
    public int height() {
        return 0;
    }
}    


public class Leaf extends Tree {
    public Leaf(int value) {
    }

    public int height() {
        return 1;
    }
}


public class Node extends Tree {
    private final Tree left;
    private final Tree right;

    public Node(Tree left, Tree right) {
        this.left = left;
        this.right = right;
    }

    public int height() {
        return 1+ Math.max(left.height(), right.height());
    }
}

(I told you this was going to be verbose. You were warned :-)

Step two: respect the OCP, son!

Now we could go on defining all kinds of functions on trees this way; but this would mean that for every new function, we need to change all of our classes. That won’t do; we don’t want to keep changing and adding to the same old files. We want to close the Tree classes for modification, but keep them open for extension; this is the open/closed principle. What can we do?

A pattern to the rescue. Have you ever wondered where it’s reasonable to use Visitor? Well, this is it. As usual, we start with a test:

@Test
public void heightWithVisitor() throws Exception {
    Tree tree = new Node(
        new Node(new Leaf(0), new EmptyTree()),
        new EmptyTree());
    Visitor height = new Height();
    assertEquals(3, tree.accept(height));
}

The implementation of visitor can be:

public abstract class Tree {
    public abstract int accept(Visitor visitor);
}

public class EmptyTree extends Tree {
    public int accept(Visitor visitor) {
        return visitor.visitEmptyTree();
    }
}

public class Leaf extends Tree {
    private final int value;

    public Leaf(int value) {
        this.value = value;
    }

    public int accept(Visitor visitor) {
        return visitor.visitLeaf(value);
    }
}

public class Node extends Tree {
    private final Tree left;
    private final Tree right;

    public Node(Tree left, Tree right) {
        this.left = left;
        this.right = right;
    }

    public int accept(Visitor visitor) {
        return visitor.visitNode(left, right);
    }
}

Note that each tree subcase provides the visitor with all the information they contain. This way we avoid getters, which is nice. The definition of Height is very similar to the Haskell example:

public class Height implements Visitor {    
    public int visitEmptyTree() {
        return 0;
    }

    public int visitLeaf(int value) {
        return 1;
    }

    public int visitNode(Tree left, Tree right) {
        return 1 + Math.max(left.accept(this), right.accept(this));
    }
}

The nice thing is that now the Height function lives in its own little object. We were able to decouple it from the Tree classes.

We still can’t forget to define a case, as the compiler will force us to implement all three methods of Visitor.

Step three: generics

Of course, the big problem with this Visitor implementation is that it only works for functions that return integers. We can solve this with Java generics:

public interface Visitor<T> {
    T visitEmptyTree();
    T visitLeaf(int value);
    T visitNode(Tree left, Tree right);
}

public abstract class Tree {
    public abstract <T> T accept(Visitor<T> visitor);
}

public class EmptyTree extends Tree {
    public <T> T accept(Visitor<T> visitor) {
        return visitor.visitEmptyTree();
    }
}
// etc.

The other way to solve the genericity problem would be to define the Height visitor as a stateful object, that has a int result() method that is not part of the Visitor interface. But we’ll leave that to some other time.

A delightful little book on this very subject is A Little Java, A Few Patterns by Matthias Felleisen and Daniel P. Friedman. In fact I think I learned the meaning of Visitor by reading this book! The authors wrote a number of books on Lisp and Scheme in a similar vein; the first one was The Little Lisper and it takes a very unusual approach to teaching.

Hope it comes in handy!

Last presentation: TDD from end to end

Sunday, March 6th, 2011

Yesterday I presented “TDD from end to end” at Codemotion in Rome. My talk was about how to use TDD to drive the development of the whole system, from the GUI to the database. The slides contain a small solved exercise, which could be a good kata for Java servlet and JDBC skills. The techniques I showed are not my own! I’m showing things I learned from Francesco Cirillo and Carlo Bottiglieri.

The slides are in Italian, but they mostly contain Java code with English identifiers: 20110305-tdd-codemotion.pdf. Enjoy!

Update: here is the video.

Il Codemotion si avvicina…

Tuesday, March 1st, 2011

Questo sabato parlerĂ² al Code Motion di TDD. Io sono alle 15.20 nella sessione “Tool and Processes.”

http://www.codemotion.it/programma-talks