Friday, May 21, 2010

Kata Two: The Pair Combinator

This is the second in a series of code katas prepared for an internal code dojo I host for the ASP.NET QA team. I share it hoping that others will practice it, and then share their own experiences in the comments. What's a code kata? I'll let Dave Thomas, who coined the term, explain its meaning.

Per request, I will target client-side JavaScript for our first few code katas, so that jQuery (or another JavaScript framework) may be used. While such a target is somewhat limiting, you can easily adapt this kata to other languages, frameworks, or environments.

I consider pair programming a fundamental part of the practice of crafting software. It's not as critical to me as, for instance, test-driven development, but I will always pair when possible. While I might not force pairing on an engineering team, I think it's quite reasonable to require some pair programming in the dojo. So I've decided that the dojo's middle hour (of three) will be paired repetitions (and pairing is certainly permissible in the first and last hour as well).

I also encourage the so-called practice of promiscuous pairing, which is changing your pairing partner frequently, after short periods of time.This works very well in a code dojo, thanks to the repetitive nature of code katas. But my experience is that, if you leave pair rotation and combinations up to folks, they tend to stay with their current partner too long. I decided to assign pairs during the middle hour, and that gave me the idea for the second kata: The Pair Combinator.

The Form

Write a web page, using only HTML and client-side JavaScript, that takes as input any number of programmer's names and the number of pairings, and produces as output pair combinations, duplicating combinations only when needed..

The manner by which input is captured, and output is displayed, is left to your creativity, provided it can be accomplished in HTML and client-side JavaScript alone.

You may use a JavaScript library, such as jQuery. You must practice TDD. You may ask anyone in the dojo to pair with you; if they aren't already paired, they must agree.

The Focus

There are several facets of this kata on which you could focus:
  • TDD
  • The user interface
  • The combinatorial algorithm
  • Manipulating the page with JavaScript
Of course, you don't have to focus on just one facet, but I found it helpful to be very deliberate and explicit about what I was focusing on for each repetition. Even though this is a relatively small problem (and page), there are many different ways to craft it. I think it's important to focus on that freedom, and the room it affords for iterative improvement. For instance, I've written discussion forums ten or more times during my career, and each time what I produce is better in some way than the last. So focus keenly on how you can improve iteration-to-iteration, in one or more of the facets.

Repeating the Kata

As with all katas, I suggest you delete all the code, both unit tests and product, between repetitions.

I think this kata is a good candidate for a time limit. On the first practice, take as much time as you need to finish. On subsequent repetitions, give yourself less time, and then shave more and more time off the limit until you can't quite finish. (And, as with any timed kata, it's important not to rush, sacrificing the quality of the form and action.)

Other ideas:
  • Try a new JavaScript framework, or none at all, for a repetition.
  • Try different implementations; not only in code, but also in the user interface (for instance, displaying results in a table versus a list).
  • Think about missing features that still stay true to the page's purpose.
Cheers,
Drew (twitter.com/anglicangeek)

If you practice this kata, please share your experience in the comments.

Thursday, May 20, 2010

Kata One: Red, Green, Refactor (or Next Test) in JavaScript

This is the first in a series of code katas prepared for an internal code dojo I host for the ASP.NET QA team. I share it hoping that others will practice it, and then share their own experiences in the comments. What's a code kata? I'll let Dave Thomas, who coined the term, explain its meaning.

As requested, I will target client-side JavaScript for our first few code katas, so that jQuery (or another JavaScript framework) may be used. While such a target is somewhat limiting, you can easily adapt this kata to other languages, frameworks, or environments.

The Preparation

Choose a JavaScript unit testing framework to use for this kata, such as jQuery's QUnit. Have the editor and browser of your choice ready to program client-side (i.e., browser-based) JavaScript.

The Form

Implement a JavaScript function that ordinalizes a number using test-driven development (TDD). Ordinalizing a number means converting it to its ordinal equivalent; e.g., 1 to 1st, 11 to 11th, 42 to 42nd. The function's specification and algorithm is less important than strictly adhering to the red, green, refactor (or next test)  continuous cycle of TDD. That cycle is:
  1. Write a failing test that specifies a single behavior of the unit you are developing.
  2. Write only enough code in the unit your are developing to make the test pass. Then ensure that all other tests still pass, as well.
  3. Examine all of the unit's code thus far written. Can it be improved? If so, make a single improvement and then run all of your tests again. Continue making improvements, one at a time, until you see no more need for improvement.
  4. Repeat the above steps for the unit's next behavior, starting with a new, failing test.
When I first started practicing TDD, I struggled to determine what tests to write first, or even at all. If you are struggling as I did, I suggest starting with these three tests:
  1. It will ordinalize 1 to 1st
  2. It will ordinalize 11 to 11th
  3. It will throw if the number argument is null
Keep adding tests, one at at time. The kata is complete when you feel you have completely specified (designed) the ordinalize function via unit tests, and all of those unit tests pass.

The Focus

In my early TDD days, I also struggled to write only enough code to satisfy the current unit test. For instance, imagine I am writing the code to make test #3 above pass. All that is required is: if (num === null) { throw "Number is null!"; }. But I can anticipate that, for instance, an array or string should throw an error, as well. So I'm tempted to write: if (typeof(num) !== 'number') { throw "num is not a number!"; }. This would make test #3 pass, but it might come at the expense of writing the other tests. And maybe I'm adding behaviors I won't actually need. (Of course, there comes a time where some generalization and anticipation makes sense, and learning when and how best to generalize is one aspect of mastering TDD.)

As you practice this kata's form, focus on writing only enough code to make the current unit test pass. Make the smallest change that makes sense. Also focus on completely specifying the ordinalize function's behavior. The first time I practiced this kata I ended with 7 tests; the last time, 18; and, the highest, nearly 30 (which I felt was over-specifying.) Find what works for you, keeping your focus on the quality of the behaviors, and be open to experimenting from repetition to repetition.

Repeating the Kata

Repeat this kata 3-5 times each time you practice it.

I suggest that you delete all the code you write, both the unit tests the ordinalize function, between each repetition of this kata. I know the temptation to save your work for reference is strong, but you'll benefit more from focusing on the form and the action of the kata, not the product. It's also much easier to walk a new road when the old road is out of sight, and one of the reasons we repeat katas is to vary the form (within its boundaries).

Deleting the code between repetitions doesn't mean you can't take notes. In fact, I've found that taking notes during the kata can be helpful (albeit sometimes distracting), and after finishing a kata, I usually examine the product after a 5-minute water-cooler break, noting what I liked, what I disliked, and what things I want to consider for future repetitions. Then, I issue the cleansing Cmd+A, Del.

Here are some other ideas to consider when repeating this kata:
  • Consider adding a time limit to a repetition, such as 10 or 15 minutes
  • Change the function to test, keeping the keen focus on the TDD cycle; for instance, instead of an ordinalize function, try an email validator (sans regular expression), a color name to hex converter that uses shortcuts (e.g., red to #f00), or a function that calculates the date of Easter using a Computus such as the Golden Number; try to choose something you could TDD in 15 minutes
  • Compare your unit tests with another programmer's before you delete the code; how do your tests compare? What can you learn from the differences? What can you learn from their unit tests?
  • Pair with another programmer, alternating who writes the test and who writes the code to make it pass; how do the unit tests produced while pairing differ from those produced alone?
  • Use a different unit testing framework, or perhaps a BDD framework; how do your tests differ? How was the experience different?
  • Don't use a unit test framework at all; this means you'll have to develop a way to run tests, define tests, and report the results; how does this experience compare to using a test framework? Do your tests look different?
Cheers,
Drew (twitter.com/anglicangeek)

If you practice this kata, please share your experience in the comments.

Wednesday, May 19, 2010

Stubbing Node Code for TDD

I've been furiously hacking with Node to build Campaign Narrative, a website for hosting and playing role-playing games online. I'm storing data in MongoDB, so I'm building a small library to use the Repository pattern on top of it. Once I had something that worked, I decided to toss my spike code and do it for real (via TDD). That's when I realized I had a problem.

The Problem
My repository library uses the node-mongodb-native library. I need to stub lots of stuff in node-mongodb-native to TDD my repository code. I tried several approaches: changing and extending prototypes, global redefinition, unshifting a folder of stubs into the require paths; none of it worked (or didn't work in a way that made me happy). Because I'd been hacking Ruby very recently, I was approaching the problem from that perspective. Then I wondered, how would I handle this in .NET? I'd use dependency injection.

My Solution
I decided to use an (admittedly very crude) form of constructor injection so I could stub my dependencies. Here is an excerpt from my mongodb_repository.js library:
require("lib/prototypes");
exports.MongoDBRepository = function(config, collectionName, deps) {
  var config = config || {};
  config.merge({
    host: "127.0.0.1",
    port: 27017
  });
  
  deps = deps || {
    Server: require('mongodb/connection').Server,
    Db: require('mongodb/db').Db
  };
  
  this.collectionName = collectionName;
  this.server = new deps.Server(config.host, config.port, {});
  this.db = new deps.Db(config.dbName, this.server)
  
  this.db.open(function(){});
};
You'll notice the third argument of my constructor function, deps. By wrapping all of my dependencies in this deps object (instead of the typical, module-level var dep = require("dep"), I can easily pass stubs in for the dependencies in my test code.

Here is an excerpt of application code that creates a repository object, without passing in deps:
var repositoryConfig = {
  host:   process.env['mongodb-host']   || "127.0.0.1",
  port:   process.env['mongodb-port']   || 27017,
  dbName: process.env['mongodb-name']   || "development" 
};

var accountRepo = new Repository(repositoryConfig, "accounts");
And here is an excerpt from my spec, which passes in stubs for deps:
the("Repository constructor function", function(will) {

  will("use a default host of 127.0.0.1 if no host is provided", function (done) {
    var stubs = {
      Server: function(host, port, options) {
        assert.equal("127.0.0.1", host);
        done();
      },
      Db: function(dbName, server) {}
    };
    stubs.Db.prototype.open = function(callback){ };    
    new Repository(null, "theCollection", stubs);
  });

});
One of the things I really like about this approach is that my tests are that much more intention-revealing, in that it's very clear what is being stubbed. I know it's a small, simple thing, but it makes me happy. I also like that I don't need any special stubbing library.

This approach works just as well with Node's built-in modules. For example, I stub the sys module for the puts function in my Willful spec'ing framework.

How do you stub with Node? Please share your own approach with me!

Cheers,
Drew (twitter.com/anglicangeek)

Missing Node crypto Functions on OS X?

While integrating the cookie-node library into the application framework I've built on top of Node, I ran into an unexpected error: the createHmac function was missing from Node's built-in crypto module. After reading some posts on Node's Google group, it seemed that it didn't like my openssl build; perhaps it's some issue with the version of openssl that ships with OS X 10.6.

To fix it, I did the following:

cd /usr/local/src
curl -O http://www.openssl.org/source/openssl-1.0.0.tar.gz
tar -xzvf openssl-1.0.0.tar.gz
cd openssl-1.0.0.tar.gz
./configure --prefix=/usr/local
make
sudo make install
cd your/path/to/node/src
./configure --prefix=/usr/local
make
sudo make install
make test

(This assumes you're using /usr/local for sources you build, as some recommend.)

Interestingly, and frustratingly, ./configure for Node still reported that openssl was missing. But make test reported no failures, and the createHmac (and other missing functions) were now in the crypto module's exports. Yay!

I post this not only so I have it for reference next time (as I re-image my MBP often), but in case someone else encounters this problem.

Cheers,
Drew (twitter.com/anglicangeek)

Tuesday, May 18, 2010

Willful, a light-weight spec'ing library for Node

Last night, I pushed the spec'ing library I made to TDD Campaign Narrative to Github. I'm calling it Willful, well, because it's full of will("do this") and will("do that"). If you're a Javascript hacker, and especially if you're a Node hacker, please check it out and let me know what you think.

Here's an example specification written with Willful:

require("willful");
var assert = require("assert");

// start a new specification:
the("function I'm spec'ing", function (will) {

  // start a new behavior:
  will("exhibit the behavior I expect", function(done) {
    // test something via Node's built-in assert module
    assert.ok(true)

    // signal that the behavior's verification is done
    done();
  });

  // start a second behavior (this one'll fail)
  will("not exhibit the behavior I expect", function(done) {
    assert.equal(true, false);
    done();
  });

});

I looked at many different unit testing and spec'ing libraries when I started to TDD my Node app, and none of them made me quite happy enough. minitest.js came closest, and the design for Willful was influenced by it.

(Bonus: If you look at Willful's own specs, you'll see my approach to stubbing dependencies in Node (such as stubbing sys.puts for reporting). I'll write another 'blog post relating how I came to that approach soon.)