implements Elegance {

// Elwyn Malethan's musings on software development, mountain biking and general navel–gazing...

Articles tagged with 'tdd'

Practical TDD: It's iterative

I employ TDD/BDD as my software development methodology. I have found over the years that it is the best way of producing good quality, well-designed code. Not only that, when employed with a customer willing to work iteratively, I have found it to be one of the most reliable ways of delivering software that fulfills the requirements the customer actually has and not what they thought the requirements were at the beginning of the project. So, as far as I‘m concerned, all the evidence I‘ve seen and experienced so far suggests to me that TDD/BDD produces the best results.

Not everyone agrees.

There are developers I respect that disagree, people who I‘ve spoken to, people who‘s writings I read and people I‘ve worked with who just do not see the benefits of TDD. And some that are cynical about software craftsmanship in general. None have made arguments that have convinced me that they‘re right to doubt the benefits of TDD. However, I‘m not a fundamentalist, I‘ll listen to arguments and enjoy having my views challenged.

One thing I‘ve noticed about many (not all) of the people that are skeptical of TDD is that they don‘t really understand what it is. A common misconception is that tests are written in advance of production code; that test code for a component is completed before the implementation. It is perhaps not surprising given TDD is referred to as a test-first methodology.

This is not at all how it has worked for me and not my understanding of what the literature on the matter describes. It is certainly not an approach for TDD I would advocate or advise.

As a result of the misunderstanding, some developers find a real barrier to being productive when trying to implement new code employing TDD. This article isn‘t written with the intention of making an argument in favour of TDD or to envangelise in anyway. Hopefully, it will go some way to address the barrier that some experience.

TDD is iterative

To illustrate the iterative nature of TDD I‘m going to write some code. The process whereby this problem will be solved will illustrate how TDD helps us understand the problem and how our solution will evolve. It will also illustrate how the resulting solution can more easily be refactored to provide a cleaner solution by relying on the tests to verify the correctness of the refactored code.

The simple problem in question is – bizarrely – based on an actual requirement I had to fulfil not so long ago. It is to place a sequence of integers from 1 to n , where n is an odd number, in a collection ordered such that 1 is placed in the middle with each successive number placed either side of 1, alternating from left to right.

Getting started

I know it‘s meant to be test–first, but I usually start with a class and a method representing the implementation. I‘m not too worried about the name of either the class or the method at the moment, nor the signature of the method. I can always change these as I go along and further clarify the requirements, usually multiple times.

class MiddleOutNumberSorter {
  def sort(count: Int): List[Int] = {
    return Nil
  }
}

Oh, and by the way, this is going to be Scala. I develop in Java for a living, Scala I develop to keep me sane. Writing software in Scala reminds me why I got into software development in the first place. The requirements are represented by Specs specifications.

So, now we get to the TDD bit, the very next thing we do is create a testcase (or a specification) with stubbed tests (or examples) for the requirements we know of or can easily deduce.

object MiddleOutNumberSorterSpec extends Specification with ScalaCheck {

  "MiddleOutNumberSorter" should {
    "reject even number counts and throw an exception" in { }
    "return a list of the same length as the count specified" in { }
    "produce 3 numbers in the correct order" in { }
    "produce 5 numbers in the correct order" in { }
    "produce 15 numbers in the correct order" in { }
  }  
}

One of the things I like about Specs is the fact that empty examples (or more specifically examples without assertions) will manifest as skipped tests and not passing ones.

One thing you will find when producing these test stubs for business requirements is that it will prompt you to think about what the requirements you have actually mean. If, in fact, you can‘t think of any tests to write it is probably an indication that you either don‘t understand the requirements or they are not well defined. Either way it means that you need to go back to the customer to clarify the requirements.

Fail, fix, repeat

Because they are stubs, none of these examples actually break our code. We‘re going to change that. So let‘s write a test that represents a real requirement. This will cause our (currently minimal) implementation to fail.

object MiddleOutNumberSorterSpec extends Specification with ScalaCheck {

  var sorter: MiddleOutNumberSorter = _

  "MiddleOutNumberSorter" should {
    doBefore {
      sorter = new MiddleOutNumberSorter
    }
    "reject even number counts and throw an exception" in {
      Array(0,2,4,10,212).foreach {=>
        sorter.sort(i) must throwA[IllegalArgumentException]
      }
    }
    "return a list of the same length as the count specified" in { }
    "produce 3 numbers in the correct order" in { }
    "produce 5 numbers in the correct order" in { }
    "produce 15 numbers in the correct order" in { }
  }  
}

Ok,now the production code fails the test criteria so we turn our attention to the implementation to address this. We do the bare minimum possible to achieve this. So the implementation now looks like this:

class MiddleOutNumberSorter {
  def sort(count: Int): List[Int] = {
    if(count % 2 == 0) {
      throw new IllegalArgumentException("sort only accepts odd numbers")
    } else {
      return Nil
    }
  }
}

“Hang on“, I hear you say “that‘s not going to sort our numbers, not even close”. You‘re right. All this does is satisfy the one requirement for which we have an example.

This is obviously no more correct than it was before in terms of satisfying the end requirements. This is a bit of a difficult concept to get over for non TDDers. Someone on the #java IRC channel once sarcastically said words to the effect:

TDD is wasting time writing code I know is wrong all day.

What it does mean is we can quickly get back to specifying more of our requirements by filling out another stub. So, on to the next example.

object MiddleOutNumberSorterSpec extends Specification with ScalaCheck {

  var sorter: MiddleOutNumberSorter = _

  "MiddleOutNumberSorter" should {
    doBefore {
      sorter = new MiddleOutNumberSorter
    }
    "reject even number counts and throw an exception" in {
      Array(0,2,4,10,212).foreach {=>
        sorter.sort(i) must throwA[IllegalArgumentException]
      }
    }
    "return a list of the same length as the count specified" in {
      Array(1,3,9,15,133).foreach {=>
        sorter.sort(i).size must_== i
      }
    }
    "produce 3 numbers in the correct order" in { }
    "produce 5 numbers in the correct order" in { }
    "produce 15 numbers in the correct order" in { }
  }  
}

And back to the implementation, again doing the bare-minimum we can to satisfy the requirement.

class MiddleOutNumberSorter {
  def sort(count: Int): List[Int] = {
    if(count % 2 == 0) {
      throw new IllegalArgumentException("sort only accepts odd numbers")
    } else {
      return (0 until count).toList
    }
  }
}

And so we continue until we have an implementation…

class MiddleOutNumberSorter {
  def sort(count: Int): List[Int] = {
    if (count % 2 == 0) {
      throw new IllegalArgumentException("sort only accepts odd numbers")
    } else {
      val numbers = new Array[Int](count);
      for (number <- 1 to count) {
        val index = if (number == 1) {
          count/2
        } else if(number % 2 == 0) {
          (count/2) + (number/2)
        } else {
          (count/2) - (number/2)
        }

        numbers(index) = number
      }
      return numbers.toList
    }
  }
}

...that satisfies the entire specification:

object MiddleOutNumberSorterSpec extends Specification with ScalaCheck {

  var sorter: MiddleOutNumberSorter = _

  "MiddleOutNumberSorter" should {
    doBefore {
      sorter = new MiddleOutNumberSorter
    }
    "reject even number counts and throw an exception" in {
      Array(0,2,4,10,212).foreach {=>
        sorter.sort(i) must throwA[IllegalArgumentException]
      }
    }
    "return a list of the same length as the count specified" in {
      Array(1,3,9,15,133).foreach {=>
        sorter.sort(i).size must_== i
      }
    }
    "produce 3 numbers in the correct order" in {
      sorter.sort(3) must containInOrder(List(3,1,2))
    }
    "produce 5 numbers in the correct order" in {
      sorter.sort(5) must containInOrder(List(5,3,1,2,4))
    }
    "produce 15 numbers in the correct order" in {
      sorter.sort(15) must containInOrder(List(15,13,11,9,7,5,3,1,2,4,6,8,10,12,14))
    }
  }  
}

Now I commit this code to version control. It‘s complete, and I can be confident that it fulfills the requirements because they are codified in unit tests. Not only that, those tests provide an invaluable resource to other developers working on the project. They now have code that when run generates a report that tells them in plain English what it should and should not do.

Being a an aspiring software craftsman I want all the code I write to be maintainable, with minimal technical debt. I want it to be sustainable in the longer term, so I'm not entirely happy with the implementation. In general, I want to reduce the number of WTFs per minute to a minimum.

The benefit

Also, I‘m becoming less keen on the imperative style and Programming in Scala promotes a more functional style using immutable objects. The thing is, having been mainly a developer of imperative languages, I'm still learning to code in a functional style – particularly in Scala – and so it doesn't quite come naturally to me yet. Without test coverage, this would be a risky approach. In my attempt to produce more functional code, I might cause it to produce incorrect results. Because I‘m new to FP, I might not really understand why. However, because I produced the test coverage as I wrote the production implementation I have a safety net which tells me instantly if I broke anything.

So after a bit of experimentation and copious runs of the specifications, I end up with the following, far more elegant solution. Although elegance is somewhat in the eye of the beholder, so I don‘t expect everyone to agree :)

class MiddleOutNumberSorter {
  def sort(count: Int): List[Int] = {
    if (isOddNumber(count)) (0 until count).map(=> numberAtIndex(i, count)).toList
    else throw new IllegalArgumentException("sort only accepts odd numbers")
  }

  private def isOddNumber(count: Int): Boolean = {
    count % 2 != 0
  }

  private def numberAtIndex(index: Int, count: Int) = {
    val middleIndex: Int = count / 2
    if (index > middleIndex) {
      2 * (index - middleIndex)
    } else {
      2 * (middleIndex - index) + 1
    }
  }
}

As I mentioned, I'm currently learning Scala and FP, so I'd love it anyone reading this could suggest alternative implementations.

First published on Dec 10, 2010. Last updated on: Dec 10, 2010.

Human fallibility: A simple argument in favour of unit testing

I was asked about TDD recently. The discussion was in the context of the polarised views with regard TDD and even unit testing. The conversation reminded me a little of the response to a post I wrote a while back.

One argument against TDD and (possibly unit testing in general) that I had in a comment to my Why TDD: Freedom to refactor post, in particular response to the assertion that unit tests evaluate the correctness of features, was the following:

You can do that with your brain and your own powers of reasoning…

The essence of this argument, as I understand it, was expressed to me recently. Essentially that – as a ‘good developer‘ – you can evaluate your code and your software yourself without the need for unit tests.

Obviously I don‘t agree.

This kind of evaluation of the correctness of your code requires constant or repeated human attention. My argument against this point of view is simple:

Human beings are fallible, they get tired, they get lazy, they get ill and they get run over by buses. Tests that rely on human beings to attend to those tests or require a human's expertise to verify the correctness of those tests are therefore not as reliable, reusable or portable as tests that can run unattended and verify their own success.

First published on Oct 28, 2010. Last updated on: Nov 16, 2010.

Unit testing with Commons HttpClient

I‘ve been adding some test coverage to some existing code today. This code under test uses Commons HTTP Client to fetch data from an external resource. I ran into problems with mocking/stubbing the response to the HTTP requests.

I am not the only one who has faced problems with this Http Client. In that article, Florin provides a good solution using a concrete subclass of HttpClient in order to mock it‘s behaviour. His article was very useful in helping me formulate my approach.

I use JMock for dynamic mock objects and so I was keen not to have to mix of JMock-based mocks and concrete mock objects. So my approach is to use JMock‘s custom actions to provide an implementation that populates the right values in the right way. Although, I had to use some reflective cheating to set the necessary values.

private static Action willRespondWith(final int code, final String status, final String body) {
    return new CustomAction("will respond with status: " + code +  ", and contents: " + body) {
        @Override
        public Object invoke(Invocation invocation) throws Throwable {
            final Object method = invocation.getParameter(0);

            final Field statusLine = HttpMethodBase.class.getDeclaredField("statusLine");
            statusLine.setAccessible(true);
            statusLine.set(method, new StatusLine("HTTP/1.0 " + code + " " + status)); //Although, 'OK' could be anything 

            final Method setResponseStream = HttpMethodBase.class.getDeclaredMethod("setResponseStream", InputStream.class);
            setResponseStream.setAccessible(true);
            setResponseStream.invoke(method, new ByteArrayInputStream(body.getBytes("UTF-8")));

            return code;
        }
    };
}

This is intended to be used as follows:

@Test
public void testSomeHttpStuff() throws Exception {

    jmock.checking(new Expectations() {{
        allowing(client).executeMethod(with(any(HttpMethod.class)));
        will(willRespondWith(200, "OK", "{some: 'value'}"));
    }});
        
    sendHttpRequest("http://some.server/some/resource.json");
        
}

Now I can simulate all sorts of responses from the external resource.

First published on Apr 26, 2010. Last updated on: Apr 26, 2010.

JavaScript BDD framework in less than 200 lines

I‘ve been doing a lot of work with JavaScript lately and so I‘ve been thinking a lot about how to effectively bring my experiences of BDD and TDD in other technologies to the party. There are a few test frameworks available, JsTestDriver by far the better looking of the lot. There is a specification framework, based on rspec as well. However, I couldn't find a JavaScript BDD story framework anywhere. So armed with some new knowledge from JavaScript: The Good Parts, I had a go at looking into what such a framework would look like. I was surprised as to how quickly I came up with a solution and how small the footprint of the end result is.

So here it is, in less than 200 lines, a JavaScript BDD Framework I've called it BehaviourJS and I've made it available under the GNU Lesser General Public License.

// ------------------------------------------------------------ Function augmentation

/**
 * Standard means of augmenting everything with new methods
 *
 * @param name the name of the new method
 * @param func the function we want invoked
 */
Object.prototype.method = function(name, func) {
    if (!this.prototype[name]) {
        this.prototype[name] = func;
        return this;
    }
};

// ------------------------------------------------------------ Should DSL

behaviourJs = {};

behaviourJs._shouldBe = function(expected) {
    if(expected !== null) {
        var exp = expected.valueOf();
        var self = this.valueOf();
        if(self === exp) {
            return;
        }
    }
    throw {
        name: 'AssertionError',
        message: 'Expected ' + expected + ' but was ' + this
    };
};

Object.method('shouldBe', behaviourJs._shouldBe);
Object.method('shouldEqual', behaviourJs._shouldBe);
Object.method('shouldBeEqual', behaviourJs._shouldBe);
Object.method('shouldBeEqualTo', behaviourJs._shouldBe);

behaviourJs._shouldNotBe = function(expected) {
    if(expected !== null) {
        var exp = expected.valueOf();
        var self = this.valueOf();
        if (self !== exp) {
            return;
        }
        throw {
            name: 'AssertionError',
            message: 'Expected not to be ' + expected + ' but was ' + this
        };
    }
};

Object.method('shouldNotBe', behaviourJs._shouldNotBe);
Object.method('shouldNotEqual', behaviourJs._shouldNotBe);
Object.method('shouldntBe', behaviourJs._shouldNotBe);
Object.method('shouldntEqual', behaviourJs._shouldNotBe);

// ------------------------------------------------------------ StoryInstance

behaviourJs.StoryInstance = function(block) {
    block.call(this);
};

behaviourJs.StoryInstance.prototype.visit = function(visitor) {
    visitor.visitStory(this);
};

behaviourJs.StoryInstance.prototype.run = function() {
    this.visit(new behaviourJs.StoryRunner());
};

// ------------------------------------------------------------ ScenarioInstance

/**
 * A runnable scenario.
 *
 * @param name the description of the scenario
 * @param block the function containing the contents of the scenario (usually
 * a series of Givens,When and Thens).
 */
behaviourJs.ScenarioInstance = function(name, block) {
    this.name = name;
    this._steps = [];

    behaviourJs.ScenarioInstance.__currentScenario = this;

    block.call();

    behaviourJs.ScenarioInstance.__currentScenario = null;
    behaviourJs.ScenarioInstance.__currentPhase = null;
};

behaviourJs.ScenarioInstance.__currentScenario = null;

behaviourJs.ScenarioInstance.__currentPhase = null;

behaviourJs.ScenarioInstance.prototype.addStep = function(step) {
    this._steps[this._steps.length] = step;
};

behaviourJs.ScenarioInstance.prototype.visit = function(visitor) {
    visitor.visitScenario(this);
};

// ------------------------------------------------------------ Step

behaviourJs.Step = function(type, meta, block) {
    this._type = type;
    this._meta = meta;
    this._block = block;
};

behaviourJs.Step.prototype.visit = function(visitor) {
    visitor.visitStep(this);
};

// ------------------------------------------------------------ StoryRunner

behaviourJs.StoryRunner = function() {
    this.storyCtx = {};
};

behaviourJs.StoryRunner.prototype.visitStory = function(story) {
    var title = 'Story: ' + story.description;
    document.writeln(title);
    var line = '';
    for(var i = 0; i < title.length; ++i) {
        line += '=';
    }
    document.writeln(line);
    for (var scenIndex = 0; scenIndex < story.scenarios.length; ++scenIndex) {
        story.scenarios[scenIndex].visit(this);
    }
};

behaviourJs.StoryRunner.prototype.visitScenario = function(scenario) {
    document.writeln('Scenario: ' + scenario.name);
    for (var stepIndex = 0; stepIndex < scenario._steps.length; ++stepIndex) {
        var step = scenario._steps[stepIndex];
        step.visit(this);
    }
    document.write("\n");
};

behaviourJs.StoryRunner.prototype.visitStep = function(step) {
    var stepDesc = step._type.toUpperCase() + ' ' + step._meta;
    if (step._block === undefined || step._block === null) {
        if (step._type === 'then') {
            stepDesc += ' [PENDING]';
        }
    } else {
        try {
            step._block.call(this.storyCtx);
        } catch(e) {
            if (e.name == 'AssertionError') {
                stepDesc += ' [FAIL : ' + e.message + ']';
            } else {
                stepDesc += ' [ERROR (' + e.name + ') : ' + e.message + ']';
            }
        }
    }
    document.writeln(stepDesc);
};

// ------------------------------------------------------------ DSL

Story = function(block) {
    return new behaviourJs.StoryInstance(block);
};

Scenario = function(name, block) {
    return new behaviourJs.ScenarioInstance(name, block);
};

Given = function(desc, block) {
    var scenario = behaviourJs.ScenarioInstance.__currentScenario;
    behaviourJs.ScenarioInstance.__currentPhase = 'given';

    scenario.addStep(new behaviourJs.Step(behaviourJs.ScenarioInstance.__currentPhase, desc, block));
};

When = function(desc, block) {
    var scenario = behaviourJs.ScenarioInstance.__currentScenario;
    behaviourJs.ScenarioInstance.__currentPhase = 'when';

    scenario.addStep(new behaviourJs.Step(behaviourJs.ScenarioInstance.__currentPhase, desc, block));
};

Then = function(desc, block) {
    var scenario = behaviourJs.ScenarioInstance.__currentScenario;
    behaviourJs.ScenarioInstance.__currentPhase = 'then';

    scenario.addStep(new behaviourJs.Step(behaviourJs.ScenarioInstance.__currentPhase, desc, block));
};

And = function(desc, block) {
    var scenario = behaviourJs.ScenarioInstance.__currentScenario;
    scenario.addStep(new behaviourJs.Step(behaviourJs.ScenarioInstance.__currentPhase, desc, block));
};

My approach is heavily influenced by my experiences of using Easyb for BDD for Java. There are a few things I haven‘t added, such as before and after hooks.

Stacktrace support in JavaScript is sketchy and differs greatly across runtimes/browsers. One solution might be to integrate this attempt at universally obtaining a stacktrace. The should DSL is not as comprehensive as Easyb. Unlike Easyb the should DSL in BehaviourJS is completely extensible. This is possible because of the nature of the JavaScript langauge.

I mentioned runtimes/browsers earlier. The other potential issue is that I have only tested this in Firefox. It‘s the product of a couple of hours hacking so it‘ll be no surprise if it fails in other browsers.

Runners, build system and IDE support.

I realise that just implementing such a framework isn‘t even half of the effort required for a test framework to enable developers to practice TDD or BDD. For this framework to be useful to me or anyone else, it will need IDE support (IDEA and Eclipse at least) and build system support (Maven and maybe Ant).

The existing JavaScript test frameworks have had a lot of work put into this area and it shows. Especially with JsTestDriver‘s IDE support, which is awesome.

Maybe next weekend I‘ll have a look at plugin this into an existing test framework, such as JsTestDriver.

Example story

A story using the above framework might look something like this.

Story(function() {
    this.description = "This is an example story";
    this.summary = {
        as_a : "role",
        i_want : "to perform some action",
        so_that : "there is some perceived benefit"
    };

    this.scenarios = [
        Scenario("Some scenario", function() {
            Given("some string", function() {
                this.someString = 'this';
            });
            And("some number", function() {
                this.ten = 10;
            });
            When("something happens");
            Then("some condition is evaluated", function() {
                this.someString.shouldNotBe(null);
                this.someString.shouldNotBe({});
                this.someString.shouldNotBe(123);
                this.someString.shouldNotBe('that');

                this.someString.shouldBe(this.someString);
                this.someString.shouldBe('this');
            });
            And("some other condition is evaluated", function () {
                this.ten.shouldBe(10);
            });
        }),
        Scenario("Checking incorect values", function() {
            Given("some new precondition");
            And("some other new precondition");
            When("something new happens", function() {
                this.animal = 'animal';
            });
            Then("some new condition is evaluated", function() {
                try {
                    thisVar.doesNotExist();
                } catch(e) {
                    // gulp
                }
            });
            And("some other new condition is evaluated", function() {
                try {
                    this.animal.shouldBe('farm');
                } catch(e) {
                    e.name.shouldBe('AssertionError');
                }
            });
        }),
        Scenario('some complex objects', function() {
            Given(' a complex object', function() {
                this.MyThing = function(val) {
                    this._val = val;
                };

                this.someObj = new this.MyThing('a value');
            });
            And('a copy of it', function() {
                this.sameObj = this.someObj;
            });
            And('a different object', function() {
                this.differentObj = new this.MyThing('a value');
            });
            Then('the object and the copy should be the equal', function() {
                this.someObj.shouldBe(this.sameObj);
                this.sameObj.shouldBe(this.someObj);
            });
            And('the object and the different one should not', function() {
                this.someObj.shouldNotBe(this.differentObj);
                this.differentObj.shouldNotBe(this.someObj);
            });
        })
    ];
}).run();

The link to JavaScript: The Good Parts above is an affiliate link. It's a great book, written by a programmer for programmers.

First published on Jan 24, 2010. Last updated on: Jan 25, 2010.

Why TDD: Freedom to refactor

Dave and Jen work for software companies that produce exciting and clever software products. Both Dave and Jen understand design patterns. They both know about encapsulation, inheritance, composition and all that jazz. They‘re both good software developers. The only difference is that Jen has taught herself to develop test-driven. Dave thinks his time is better spent writing production code.

Dave and Jen started their current project at the same time. Dave spent some time up–front to carefully design his architecture to the requirements and implemented all the features. Dave added some unit tests, but only as an afterthought. Dave is confident that his architecture is well suited to providing a maintainable solution to the requirements specified. Dave is OK with the fact he has less than 25% test coverage.

Jen used TDD, she started off by adding some tests to represent some of the requirements and implementing production code to pass those tests. She did this iteratively and in small digestible chunks until she had satisfied all of the requirements. Jen changed the architecture of the project frequently. She refactored as she went, renaming classes and methods so that they better represented their function, moving code and responsibilities between classes to continually improve the design of the software. She did this safe in the knowledge that her tests would pick up any errors introduced. Jen builds up test coverage of over 80%.

As always happens in a software project, the requirements change. In Dave‘s case, management decided that – for political reasons – Dave needed to completely change the way his product worked. Jen‘s customer‘s priorities changed. To stay competitive, they needed to have different features. In both cases – as ever – time was short and deadlines were tight.

Both Jen and Dave found that their existing design wasn‘t really suited to the new requirements. Dave was concerned about the deadline and the time it would take to evaluate the correctness of any change he made in the design of the software. He has no timely or repeatable means of doing this. So Dave added the feature without changing the design. He knew it wasn‘t ideal and that the he would need to change the architecture at some point in the future. Given the time constraints, Dave believed he was being pragmatic.

Jen – on the other hand – had been refactoring the code extensively throughout the development of the project. Jen recognises an alternative design that would elegantly accommodate this new requirement and refactors. She runs the tests to see if she broke something. A few of them fail. So she fixes them and runs the tests again, safe in the knowledge that her tests represent the requirements.

Over the next few years a number of new features are requested by both Dave‘s and Jen‘s customer(s). Each time, Dave opts for the change that least affects the existing code-base. Each time Dave‘ project becomes more like a ball of mud. Dave becomes more and more resistant to new features. He started asking management for some “engineering time“ to refactor the code and have the time to evaluate it‘s correctness. This – he knew – would take some time.

In the same time, Jen‘s team have been doing nothing but implementing new features. The design of the software has changed frequently in that time. She doesn‘t need any “engineering time”, her tests evaluate the correctness of every feature she adds.

Dave has become scared of changing the code, he doesn‘t know what he might break.

Jen breaks the code every day. She‘ll know in seconds what she‘s broken and what she needs to do to fix it.

The design patterns link above is an affiliate link. Any and every software developer should have a well–thumbed copy of this book.

First published on Jan 10, 2010. Last updated on: Oct 28, 2010.

TDD in JavaScript intensive software

I recently switched jobs. I left Smartstream for somewhere closer to home. I did this primarily to avoid the commute from Cardiff to Aztec West, in Bristol. I'll be glad to avoid that drive on the M4 every day. I joined Move, who are based in Utah but have a development office not too far from Cardiff.

Having been working in the familiar world of server–side Java before Christmas, I‘ve now moved to the team that work on what we call the “middleware”. Primarily, this is the client software that runs on set–top boxes or web browsers. This is therefore almost entirely JavaScript.

Developing software that is primarily JavaScript is a new experience for me and one I‘m relishing, if with some trepidation. After a bit of Googling, I‘ve basically concluded that there isn‘t vast support for TDD for JavaScript development. This is especially true of IDE support. One thing that does look promising is JsTestDriver, though I‘ve been having trouble getting it to work reliably. This is most likely lack of familiarity with both JavaScript and JsTestDriver.

This is challenging stuff, but that‘s great as far as I‘m concerned.

First published on Jan 5, 2010. Last updated on: Jan 5, 2010.

Taking the fear out of change: BDD is essential

During the lifetime of a project, requirements are going to change. The world moves quickly, customers change their minds. You‘re just going to have to deal with it .

So, do you choose a development methodology that tries to manage or contain that change or do you accept the fact that it‘s going to happen and embrace that change?

There are two things I always keep in mind when working on a software project. These are Kent Beck's you ain't gonna need it and Rory Marinich's be less shit.

Keep the requirements brief and focussed: only enough for 2–3 weeks of work. Few people have the attention span for more. Deliver only what you know you need and then revise according to the inevitable evolution in priorities — eradicate any shortcomings, de–shit. The only software development model that supports this is one that repeatedly releases software in short iterations.

It also has to be one that takes the fear out of change. A really good way to do that is to have the security blanket of high unit–test coverage. A good way to get high unit–test coverage is to TATFT. An automatic way to TATFT is let the requirements drive and shape your code by using BDD.

So, embrace change, test–first, use BDD and TATFT.

First published on Aug 17, 2009. Last updated on: Dec 29, 2009.

Testing context for UrlRewrite and JUnit4

Absolutely ages ago, I found this great article on JUnit testing for UrlRewrite by Sujit Pal. It was very useful as at the time as I was looking for a way of testing that my usage of UrlRewrite was working correctly without having a servlet container running. Together with my contribution, both inbound and outbound rules are covered.

The solution is great for JUnit 3 but not really in the spirit of JUnit 4, where the test cases aren't necessarily part of an inheritance hierarchy, as this article demonstrates.

I had cause to test some rewrites again recently. However, I‘ve moved over to JUnit4 as a preference these days, so I decided to refresh Sujit‘s solution, decouple it from TestCase.

package some.pakage.name;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.tuckey.web.MockRequest;
import org.tuckey.web.MockResponse;
import org.tuckey.web.filters.urlrewrite.Conf;
import org.tuckey.web.filters.urlrewrite.RewrittenUrl;
import org.tuckey.web.filters.urlrewrite.UrlRewriteWrappedResponse;
import org.tuckey.web.filters.urlrewrite.UrlRewriter;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/**
 * <p>A context for testing UrlRewrite rules for JUnit4</p>
 */
public class UrlRewriteTesting {
    //----------------------------------------------------------------------- Instance Properties

    protected Conf conf;
    protected UrlRewriter rewriter;

    //----------------------------------------------------------------------- Constructors

    public UrlRewriteTesting(Conf conf) {
        org.tuckey.web.filters.urlrewrite.utils.Log.setLevel("DEBUG");
        this.conf = conf;
        rewriter = new UrlRewriter(conf);
    }

    public UrlRewriteTesting(String pathToCfg, String confFile) throws FileNotFoundException {
        this(new Conf(new FileInputStream(pathToCfg + "/" + confFile), confFile));
    }

    //----------------------------------------------------------------------- Instance Methods

    /**
     * Assertion to rewrite the URL using the UrlRewriteFilter and verify
     * that fromUrl is rewritten to toUrl using rewriting rules in conf.
     *
     * @param fromUrl the URL to be rewritten from.
     * @param toUrl   the URL to be rewritten to.
     */
    public void assertInboundRewrite(String fromUrl, String toUrl) {
        RewrittenUrl rewrittenUrl = rewriter.processRequest(new MockRequest(fromUrl), new MockResponse());

        assertNotNull("Could not rewrite URL from:" + fromUrl + " to:" + toUrl, rewrittenUrl);

        assertEquals("Rewrite from:" + fromUrl + " to:" + toUrl + " did not succeed", toUrl, rewrittenUrl.getTarget());
    }

    /**
     * Tests that an outbound url is processed correctly by the outbound rules
     *
     * @param fromUrl the url as you would be writing it in your JSPs
     * @param toUrl what you expect it to be rewritten to when rendered
     */
    public void assertOutboundRewrite(String fromUrl, String toUrl) {
        UrlRewriteWrappedResponse wrappedResponse =
                new UrlRewriteWrappedResponse(new MockResponse(), new MockRequest(fromUrl), new UrlRewriter(conf));

        assertEquals("Rewrite from:" + fromUrl + " to:" + toUrl + " did not succeed", toUrl, wrappedResponse.encodeURL(fromUrl));
    }

}

Usage

Below is an example of how SeemoreJ's rewrite rules in urlrewrite.xml for this site might look for the home page. At the time of writing, this site does not use UrlRewrite, so it's entirely hypothetical.

<!-- Index/Home -->
    <rule>
        <from>^/$</from>
        <to>/seemore?sjController=blog&amp;sjAction=home&amp;sjFormat=html</to>
    </rule>
    <rule>
        <from>^/index.(xml|html)$</from>
        <to>/seemore?sjController=blog&amp;sjAction=home&amp;sjFormat=$1</to>
    </rule>

    <outbound-rule>
        <from>/seemore\?sjController=blog&amp;sjAction=home&amp;sjFormat=(xml|html)</from>
        <to>/index.$1</to>
    </outbound-rule>

I might be making numerous minor or major changes to this file and I want the unit tests to defend against unwanted side-effects. So the test case below will (hopefully) make sure I don‘t mess things up.

package com.malethan.blog.urlrewrite;

import some.pakage.name.UrlRewriteTesting;
import org.junit.Test;

import java.io.FileNotFoundException;

public class UrlRewriteRulesTest {
    //----------------------------------------------------------------------- Instance Properties

    UrlRewriteTesting context;

    //----------------------------------------------------------------------- Constructors

    public UrlRewriteRulesTest() throws FileNotFoundException {
        context = new UrlRewriteTesting(System.getProperty("basedir") +"/src/main/webapp/WEB-INF", "urlrewrite.xml");
    }

    //----------------------------------------------------------------------- Tests

    @Test
    public void testIndexInbound() {
        context.assertInboundRewrite("/", "/seemore?sjController=blog&sjAction=home&sjFormat=html");
        context.assertInboundRewrite("/index.html", "/seemore?sjController=blog&sjAction=home&sjFormat=html");
        context.assertInboundRewrite("/index.xml", "/seemore?sjController=blog&sjAction=home&sjFormat=xml");
    }

    @Test
    public void testIndexOutbound() {
        context.assertOutboundRewrite("/seemore?sjController=blog&sjAction=home&sjFormat=html", "/index.html");
        context.assertOutboundRewrite("/seemore?sjController=blog&sjAction=home&sjFormat=xml", "/index.xml");
    }
}

First published on Dec 20, 2008. Last updated on: Dec 30, 2009.

jMock 2.x more expressive than 1.x?

jMock 2.5 has been around since July this year, and 2.x for much longer, but I've only recently used the 2.x API. I was pleasantly surprised. It makes great use of Generics to allow concise creation of mock objects and improves the the ability of a developer to rely on compiler/IDE support in specifying expectations. I‘m not so sure that the new expectation format is necessarily an improvement however.

In jMock 1.x I would have expected to have to write the following code (within a JUnit test case extending MockObjectTestCase) to create a mock object, implementing an arbitrary interface called Subscriber, then using it as an argument in some production code I want to test in isolation.

Mock mockSubscriber = mock(Subscriber.class);

Publisher publisher = new Publisher();
publisher.add( (Subscriber)mockSubscriber.proxy() );

It‘s not that concise and there‘s a bunch of typing I‘d rather not be doing. More generally, I‘ve found that a major improvement that Java 1.5 brought to the party was the syntactic candy that allows far more concise, and sometimes expressive source code.

This is illustrated in the example below that uses the jMock 2.x syntax

final Subscriber subscriber = mock(Subscriber.class);

Publisher publisher = new Publisher();
publisher.add(subscriber);

No casting and no reference to to some mysterious method called ‘proxy‘. It makes more sense in terms of the developers intention (that is to create mock object) and is less verbose.

Expressiveness vs Convenience (or is it ideology vs pragmatism?)

The way in which a developer might express expectations using jMock 2.x, I‘m not so sure it‘s an improvement. Certainly not when one considers the way in which Rspec or Mocha allows one to express the same thing.

Using jMock 1.x I might have expected to express an expectation using the following form.

mockSubscriber.expects(once()).method("receive").with( eq(message) );

There are a bunch of parentheses that are in the way but, that aside, it does kind of read in a way that might be considered natural language This is great because it is easy to read, even to someone who may not be a developer. Put in another way, it means that it allows a developer to express a solution that is closer to the way one might be thinking about it. That is, without having to model the solution in terms of the constraints of the Java language – even though it is syntactically valid Java code.

jMock 2.x employs the following approach.

checking(new Expectations() {{
    oneOf (subscriber).receive(message);
}});

One major advantage of the 2.x approach is that through the use of Generics any typo‘s in relation to the method names specified in the expectation will be caught at compile-time (or in the IDE) rather than at run-time. In addition, for those using a quality IDE (A) (there‘s only one IMHO :p ) one can take advantage of code-completion. I suspect that this may have been the major motivation in implementing it in this way. It was certainly a pleasurable experience being able to make more use of the productivity features in my IDE. The 2.x approach is also far more concise, which is a virtue.

It could hardly be said that it reads in a natural way however. Whilst reading the 1.x format it almost sounds like English. Reading the 2.x example would sound like you‘re learning English, and not doing too well!

Using a more natural language

If thought of on the same time-scale as human history – and all the technologies and skills humankind has developed over the millennia – software development, and computing in general could be considered a technology still in it‘s infancy. Not just computing either! The internal combustion engine was invented over a century ago, it‘s still only 30% efficient and our cars are still propelled by it!

It is no surprise therefore that some might consider that most programming languages pose a significant productivity shortcoming, despite being the result of decades of development. They force developers to express solutions (be it a single test case or an entire application) in terms that are specific to the programming language being used. This is also true of frameworks in languages that don‘t necessarily have quite as restrictive a syntactic or runtime straitjacket. TestUnit in Ruby being a case in point when compared to Rspec.

This is why frameworks such as Rspec are such a joy to use. They allow a developer to express solutions in terms that are far more like natural language. Not by coincidence are frameworks such as this far more suited to the problem domain in which they are employed. Moreover Rspec does this all within the constraints of the Ruby syntax and specification.

The whole concept of expressing solutions using a more optimal grammar is described in far more depth and far more articulately in Sergei Dmitriev‘s article on language oriented programming. He is selling a product in this article but that‘s not a crime and it‘s interesting nonetheless.

The code examples in this article have come straight from the jMock website, where there are many more great examples of usage.

First published on Dec 5, 2008. Last updated on: Dec 30, 2009.