ChromeWatir release 1.0.0

Every now and then we discuss ways of better automating the manual tests which accompany our web applications. This is especially poignant right now as both the development and test teams have been recently reduced in size. We have had some success with Watir in the past, but it was always dependent on Internet Explorer and Windows. So it’s cool to read that there is now an equivalent for Chrome.

ThoughtWorkers on Open Source: Announcing ChromeWatir release 1.0.0

Television and Online Communities

There are lots of online communities, filled with active and passionate people – exactly the sort of people TV would like to court, both as consumers and as providers of (cheap?) media content. However, most attempts by TV companies to engage and participate in the on-line culture have been pitiful.

How is it that organisations with such marketing power have continually failed to make sense of this opportunity?

Scott Stead has written a thought-provoking article on the subject, and (in the manner of on-line communities) visitors have enhanced it further with their own comments.

Television and Online Communities

Options for developing mobile apps: PhoneGap, Palm Pre, etc.

Mobile application development is certainly a hot topic at the moment. People seem to be climbing over one another to produce iPhone apps, and Google’s Android is never far from the tech news. But there are also other players, and several want to enable a more familiar web development experience on mobile devices.

SitePen Blog » PhoneGap, Palm Pre, and the State of Mobile Apps

A structured way to work with user stories

For someone steeped in the traditional idea of requirements and features, working with agile user stories is often hard to handle. I have invested a lot of time over recent months attempting to build a good understanding of what a user story is, and how it differs from a feature, a change or a requirement. Marc McNeill has an interesting article (with slides!) about how he deals with this kind of issue in product workshops.

What is the story? | dancingmango

Who needs Flash? Having fun with Canvas and SVG

Ever since the dawn of the web, the lack of a symbolic graphics format has been a glaring omission. I’ve never been very comfortable with the only option being to step outside the browser and use a plugin such as Flash, Silverlight, or a Java applet.

Now, eventually, it seems that support for, adoption of, and frameworks to use one of the contenders, SVG, are finally taking off. Take a look at these examples built using SproutCore and SVG:

Ajaxian » Who needs Flash? Having fun with Canvas and SVG

Stephen Colebourne’s Null-default and Null-safe operators

An interesting proposal to solve some of the common, and tedious, issues around Java nulls. Particularly comforting is that I have already separately implemented ?: with very similar semantics in my Stringtree template language.

Stephen Colebourne’s Weblog

High-energy stand-up meetings

For a variety of reasons, this morning’s stand-up meeting was a bit of a lifeless affair. I can recall times in the (relatively recent) past when such meetings were an invigorating start to the day.

Sarah Taraporewalla has some suggestions for adding a bit of energy to morning stand-up meetings.

Sarah Taraporewalla’s Technical Ramblings » Improvements to the usual stand up meetings

Martin Fowler dislikes rules engines. I’m not so sure

There’s no doubt that a generic rules engine can sometimes be a solution in search of a problem. The work to implement and manage both the rules and their interfaces with external systems can often completely dwarf any work which might be needed to implement the same behaviour in a regular programming language.

Martin Fowler has recently written about this problem in his “bliki”, and comes down in favour of always putting the effort in to work on a programming language solution alongside any exploration of a rules engine approach.

MF Bliki: RulesEngine

However, rather than seeing this as a reason to distrust the idea of rules engines as a whole, I prefer to see this is a problem with the implementation of traditional rules-engine technology. There is an argument, for example, that current fan favourite language Erlang is largely a rules engine.

The history or rules engine development is long, and many of the common conventions have a largely historical basis. The choice to represent rules in a text file represented as some lisp-based format (or a slightly more modern equivalent using XML), for example, is not really key to the concept of a rules engine. Likewise the heavyweight and single-threaded way that many rules engines operate is also mainly a historical implementation choice.

A light weight and efficient rules engine, well-integrated with the host language or environment is entirely possible, but despite several searches around the software universe I have found very few candidates, and none of the usual suspects, which work this way.

Maybe I ought to dust off my own implementation again ;)

How to Write a Spelling Corrector

A while ago someone asked me for an estimate on adding “did you mean …” spelling correction to a search facility in some software. I replied with a bunch of hand-waving and weasel words about different approaches and the need for more detail on customer requirements and then ran away to lunch.

Later, I spent a few minutes searching and found How to Write a Spelling Corrector which definitely seems to be a good starting point.

Managing large stories on agile projects, our approach

In theory, an agile story is a simple and obvious thing with many purposes. A description of some desired usage; a token for discussion; a prompt for acceptance tests; a grain around which to gather more detail. In practice, a story can sometimes be more like a traditional feature requirement, or more like a delivery contract. In these cases, estimating, developing, and delivering the story can provoke problems, risk, and conflict.

One such case is when a story is too large for comfortable estimation. Commonly this arises when a story is driven by a desire for a feature or sweeping change – something easy to give a name to, but complex in its detail. We have faced at least one of these most iterations.

Bill de hÓra discusses some approaches to tackling such large stories in a recent blog post:

Bill de hÓra: Managing large stories on agile projects

In our team we typically tackle the problem slightly differently. The items on our progress wall are represented by brown A5 envelopes, each with summary information (title, id, estimate) written in large, friendly letters on the outside, and an accumulation of detail (notes, time spent, diagrams, etc.) inside. To stop the contents falling out, the envelopes are all placed on the wall with the opening on the side.

Why do I mention this? We use a quick of this to deal with large stories. A story too large to estimate and develop on its own is represented by an envelope with the opening at the bottom. This implies that such stories can not accumulate detail of their own, but only reference other stories. We split the large customer story into several internal stories, estimate, annotate an develop them independently, but do not consider the main story complete until all the component stories are also complete. To show the relationship we write the ids of the component stories on the outside of the “vertical” envelope.

This approach seems to work. Stakeholders still have visibility of the status of the large story, and the development team is free to implement the component stories in parallel or in sequence, in whatever order is most effective and efficient.

Monkey testing

I love this idea. Pseudo-random test cases to simulate mass usage by “realistic but sometimes thoughtless” users. Especially when augmented with audit trails so that failures can be easily repeated for fixing.

DanNorth.net » Monkey business value

This impatient monkey – dancingmango

Test-Driven Development of HTTP and REST interfaces with Mojasef

Test-Driven Development (TDD) of HTTP and REST interfaces can be tricky. This post contains some examples of how to do it using the open source Mojasef toolkit. I was prompted to write this post after recently finding and fixing an irritating bug using just this technique.

First, let’s set the scene. In TDD the rules are very simple: No production code is written without a failing test; just enough code is written to satisfy the current set of tests; duplication is mercilessly refactored. TDD is a very powerful and effective technique which can improve both the quality and delivery time of software. HTTP and REST interfaces provide access to a system or component using the HTTP protocol. This access may be by fetching HTML or WML pages, for example, or it may be by sending, receiving and updating resources in some other format such as XML or JSON.

For a first scenario imagine we have an existing HTTP interface for which we want to write a client using TDD. This service is relatively simple to start with. To send a message requires a POST request to a particular URL with two parameters “destination” and “text”. If the destination is valid, the text message is sent to the destination and a “200″ status code is returned. If the destination is not recognized, a “404″ status code is returned. This interface is so simple that it is tempting to just write the client, test it manually and move on. But if we were to do that, then we might not think of all the test case possibilities, and there would be no regression tests to help protect the software from unexpected side-effects later. So we opt to do the right thing, and use TDD.

For the sake of simplicity, I will assume we are using the Stringtree HTTPClient as described in an earlier post. So let’s start with a simple test to make sure the code compiles and the test libraries and stuff are in place:

import org.stringtree.http.*;
 
public class MessageSendingTest extends junit.framework.TestCase {
  public void testExceptionFromUnknownURL() {
    Form form = new Form();
    form.put("destination", "name@example.com");
    form.put("text", "hello from HTTP");
    HTTPClient client = new HTTPClient();
    try {
      client.post("http://localhost:9999/send", form);
      fail("should throw an exception");
    } catch (Exception e) {}
  }
}

This test serves two purposes. First, compiling it helps drive the structure of the test case, what classes need to be imported and so on. Second it documents the expected behaviour of our client if the server is not running or not where it is expected to be. I always like to start with this sort of “null” test case wherever possible. Once we get this test working we are ready to move on to the next step, testing against an actual server.

It might be possible to test against a real server, perhaps by manually examining log files, or checking the actual receipt of a message. Feel free to do that, but understand that that is really integration testing rather than unit testing, and neither helps us design and debug the client, nor document and enforce the proper behaviour of our code once we move on to other work. To gain these benefits we need a server which may be started, examined and stopped quickly and under the control of a simple unit test. This is where Mojasef comes in.

Mojasef is a server and web application framework designed for efficient test-driven development of web applications. Although usually used for building applications, it is just as suitable for building test harnesses. In this case we will build a simple application which implements the HTTP interface described above. And yes, we will do it using TDD, so we leave the MessageSendingTest for the moment and start a new one to drive our test harness without requiring HTTP. As usual, I start with a “null” test to get started:

public class MessageHarnessTest extends junit.framework.TestCase {
  MessageHarness harness;
 
  public void setUp() {
    harness = new MessageHarness();
  }
 
  public void testNoAction() {
    assertFalse(harness.wasCalled());
  }
}

This won’t compile without a MessageHarness class, so let’s make the minimum necessary.

public class MessageHarness {
  public boolean wasCalled() {
    return false;
  }
}

Good, our test now runs, so let’s add some behaviour. First another test:

  public void testCalledWithoutArguments() {
    harness.send();
    assertTrue(harness.wasCalled());
  }

To make this compile we need to add another method to MessageHarness

  public void send() {
  }

Our new test fails, so we need to make it work.

public class MessageHarness {
  private boolean called = false;
 
  public boolean wasCalled() {
    return called;
  }
 
  public void send() {
    called = true;
  }
}

That seems enough to start with. Now back to the main test case. Add a new test to call the application we have just built over HTTP and check that all the communication stuff works. With a bit of refactoring to keep the tests clean and duplication low.

import org.stringtree.http.*;
import org.stringtree.mojasef.standalone.InlineServer;
 
public class MessageSendingTest extends junit.framework.TestCase {
  HTTPClient client;
  Form form;
  InlineServer server;
  MessageHarness app;
 
  public void setUp() throws Exception {
    client = new HTTPClient();
    form = new Form();
    app = new MessageHarness();
    server = new InlineServer(app, "9998");
    server.start();
  }
 
  public void tearDown() {
	server.halt();
  }
 
  public void testExceptionFromUnknownURL() {
    form.put("destination", "name@example.com");
    form.put("text", "hello from HTTP");
    try {
      client.post("http://localhost:9999/send", form);
      fail("should throw an exception");
    } catch (Exception e) {}
  }
 
  public void testHarnessWiring() throws Exception {
    form.put("destination", "unknown@example.com");
    form.put("text", "hello from HTTP");
    assertFalse(app.wasCalled());
    client.post("http://localhost:9998/send", form);
    assertTrue(app.wasCalled());
  }
}

This probably needs a bit of explanation. The MessageHarness class we produced above is a Mojasef web application. Really, without any other configuration, base classes or nonsense. It’s just a “plain old Java object” (POJO). The job of the Mojasef code is to take an object of that class and make its methods available as HTTP URLs.

To serve it over HTTP we could use a MojasefServlet and run it in any Servlet Container, but for this test we want an ultra-light server which can be started and stopped in a test. So we use the InlineServer provided in the Mojasef jar. It’s a real HTTP server which you can use from a regular web browser, but it’s mainly designed for streamlined use in tests.

This server is configured to serve the MessageHarness application on port 9998. Having configured the server we start it in startUp and stop it in tearDown to ensure that nothing is left behind between tests.

The new test makes a HTTP request to the freshly started server, then checks (by calling the MessageHarness method we created earlier) that the test harness application was successfully called. This verifies that the server has been correctly started and called.

It’s still not really testing the message API. To do that we need more tests.

Now, we know from the introduction above that our resource should return a HTTP 404 (“not found”) error if we try to send to an unrecognised address.

  public void test404FromUnknownDestination() throws Exception {
    form.put("destination", "unknown@example.com");
    form.put("text", "hello from HTTP");
    Document result = client.post("http://localhost:9998/send", form);
    assertEquals("404", result.getHeader(HTTPClient.HTTP_RESPONSE_CODE));
  }

Making this test work is pretty simple, especially as we have no other tests which say anything about the HTTP Response code. The only “cleverness” is that we now need to use some slightly smarter features of the Mojasef code.

import org.stringtree.finder.StringKeeper;
import org.stringtree.mojasef.HTTPConstants;
 
public class MessageHarness {
  private boolean called = false;
 
  public boolean wasCalled() {
    return called;
  }
 
  public void send(StringKeeper context) {
    called = true;
    context.put(HTTPConstants.RESPONSE_CODE, "404");
  }
}

Mojasef will try a variety of ways to call a public method. We have seen the basic one – a method with no parameters mapped directly to a URL. This is another one – a method taking a “context” as an argument. This context will be pre-loaded with any POST or URL parameters, as well as any request headers and plenty of other stuff which is not of interest right now. This context also provides a way of setting information to be sent back to the client.

Now, our application code is passing all its tests, but it does so by returning a “404″ error code for all requests. This is not really desirable behaviour, so we need another test:

  public void test200FromKnownDestination() throws Exception {
    form.put("destination", "known@example.com");
    form.put("text", "hello from HTTP");
    Document result = client.post("http://localhost:9998/send", form);
    assertEquals("200", result.getHeader(HTTPClient.HTTP_RESPONSE_CODE));
  }

This test fails, so we need to modify the application to add some understanding of the supplied form data.

import org.stringtree.finder.StringKeeper;
import org.stringtree.mojasef.HTTPConstants;
 
public class MessageHarness {
  private boolean called = false;
 
  public boolean wasCalled() {
    return called;
  }
 
  public void send(StringKeeper context) {
    called = true;
    String destination = context.get("destination");
    if ("known@example.com".equals(destination)) {
        context.put(HTTPConstants.RESPONSE_CODE, "200");
    } else {
        context.put(HTTPConstants.RESPONSE_CODE, "404");
    }
  }
}

Now we reach an interesting point in the development process. It is perfectly feasible to continue in this vein, step-by-step bringing the application into existence. However, even the streamlined InlineServer still needs to set itself up, bind and unbind ports, deal with network traffic and so on. This is considerably slower than a regular method call, and as more tests are added the test case will continue to slow down.

The advantages of the Mojasef approach to web applications really begin to pay off at this point. The tests we already have prove the basics of HTTP Communication are working, so further tests do not really need to bother with HTTP, provided the tests are testing exactly the same code. Luckily (as pointed out earlier) a Mojasef application is just a regular Java class, which needs no modification to be tested using regular JUnit tests. Here are the same tests as above, but implemented as simple method calls:

import org.stringtree.finder.StringKeeper;
import org.stringtree.mojasef.HTTPConstants;
import org.stringtree.mojasef.HTTPConstants;
 
public class MessageProcessingTest extends junit.framework.TestCase {
  StringKeeper context;
  MessageHarness app;
 
  public void setUp() {
    context = new MapStringKeeper();
    app = new MessageHarness();
  }
 
  public void test404FromUnknownDestination() throws Exception {
    context.put("destination", "unknown@example.com");
    context.put("text", "hello from HTTP");
    app.send(context);
    assertEquals("404", context.get(HTTPConstants.RESPONSE_CODE));
  }
 
  public void test200FromKnownDestination() throws Exception {
    context.put("destination", "known@example.com");
    context.put("text", "hello from HTTP");
    app.send(context);
    assertEquals("200", context.get(HTTPConstants.RESPONSE_CODE));
  }

I shall stop there, leaving the development of the rest of the application to interested readers.

From the above steps, I hope you can see that the normal process of Test-Driven Development is quite possible for both web applications, and web-application clients. When using a framework which gets all the fiddly stuff out of the way it can even be as simple, quick and productive as in-process development.

5 Trends That Will Change Media in ’09

One of my areas of interest is sales and delivery of mobile content. Sometimes it feels like a dead market, but my opinion was enlivened by reading an article from Steve Rosenbaum which puts a distinctly positive spin on the whole area.

Steve Rosenbaum: 5 Trends That Will Change Media in ’09

Maybe there are good times ahead for those who can do it right!

The Correct Ratio of Agile Testers to Developers? It Depends.

A hot topic in software development circles at the moment is the interaction and demarcation between “developers” and “testers”. Development uses an agile approach but it’s sometimes hard to see how this sits with the testing folks, particularly as most stories seem to move snappily through development then pile up in testing. Sometimes it seems as if a team needs more testers. Sometimes it seems as if a team should reduce or dispense with testers altogether. Sometimes it seems as if roles and responsibilities should change completely.

I wish I knew an answer to this, but at least it is encouraging that others are also considering and writing about these issues.

InfoQ: The Correct Ratio of Agile Testers to Developers? It Depends.

Nielsen top 10s for 2008

A really fascinating look at different slices of US life. Top 10 grossing movies, sure, but also mobile phones, product placements, favourite commercials, and plenty more.

THE NIELSEN COMPANY ISSUES TOP TEN U.S. LISTS FOR 2008 (PDF)

How to Do Everything with PDF Files

A brilliant summary of a whole load of free tips and tricks for working with PDF files. Never get cross with Acrobat or PDF restrictions again!

Adobe PDF Guide: How to Do Everything with PDF Files

Thanks to Tim Merritt for finding this one.

Tactics, Strategy and SOA in the cloud – conflicting views

I’m in two minds about Service-Oriented-Architecture (SOA). On the one hand it seems obvious that future systems will need to inter-operate increasingly in order to gain business benefits without requiring complete software development projects. On the other hand, I am distinctly under-impressed by the current approaches to SOA, and even by the emphasis on services rather than the equally applicable resources, messages, or processes as the integration building blocks.

Here are a bunch of conflicting views on this area which have collected in my “blog this” queue over the last few days:

InfoQ Article: Will Cloud-based Multi-Enterprise Information Systems Replace Extranets?

Will Cloud-based Multi-Enterprise Information Systems Replace Extranets? (confusingly, a different article with the same title!)

Meme Agora: Tactics vs. Strategy (SOA & The Tarpit of Irrelevancy)

Enterprise Java Community: Extend the Data Grid With Hub-less Messaging

Services & Workflows: SOAP and REST with WCF and WWF

Year of the cloud

SOA equals Integration?

More Cloud platforms: Hadoop, Eucalyptus, 10gen

A lot of the cloud computing hype is grabbed by Amazon and Google, but alongside those giants of the field there are a lot of smaller projects and organisations trying to push and grow cloud concepts. Here are a few which I have bumped into recently.

Cloud platforms of the future: Hadoop and Eucalyptus | Negative Approach – CNET News

10gen

Searching for the perfect project hosting

I’m still searching for decent project hosting. I now have several projects on the go, and several others bumping around in my head, and the fuss and bother of tying together all the various bits of a distributed software project development is making my head hurt.

All the bits I need are available separately, but so far I have not been able to find any single provider (free or paid for) which offers the combination of features I need. Essentially these are:

  • Version control. Ideally git, but at a pinch one of the other distributed VCS tools or even subversion would probably do if everything else was in place. GitHub seems good for this.
  • A project wiki. Using any other system for project docs just seems so clumsy. There are plenty of these; I use WikiDot for one project.
  • Sensible bug/feature tracking. This is a bit more tricky – there is plenty of bug-tracker software, but not much that works equally well for managing unimplemented feature stories and associated tasks. Ideally this should link in with the version control, allowing code and change metadata to be updated in one go. Trac seems a possibility for this.
  • Calendar management. For recording and communicating meetings, deadlines etc.. Something which works well with calendar syndication, so that anyone working on the project can see project events in with the rest of their appointments. Plenty of these: Google calendar, 30 boxes, etc. They all have their quirks, though.
  • Task (todo) management. I find it amazing that task management is so poor in on-line calendars. There are standalone task tools such as Remember The Milk, but it is integration which is needed.

There are also a few other features which are definitely in the “useful to have” category, but I’m practical enough to use manual or off-line tools if necessary.

  • Effort recording, tracking and reporting. For velocity tracking, process improvement, and even billing.
  • Collaborative planning and prioritisation. Mingle tries to simulate a task wall, but is somewhat clumsy and irritatingly expensive; I have heard of on-line tools to run “Planning Poker” sessions, but as usual, not integrated with anything else.
  • Continuous Integration. I’m not aware of any really smart tools to make use of distributed version control for this, yet. Our Cruise Control installation just stops and complains when something breaks, for example, but it should be possible to just “park” the failing patch and continue building with others in a real dvcs-based approach.

If anyone has any suggestions – or wants to build a product which does all this stuff – please let me know!

For interest, here are a few associated links.

Cuberick: Distribute Your Software Just Like Ubuntu With Launchpad

Comparison of open source software hosting facilities: Wikipedia

Deliberate Practice and Talent is Overrated

I was very interested to read mark Needham’s thoughts on a book “Talent is Overrated”, in particular the aspect of deliberate practice.

Talent is Overrated: Book Review at Mark Needham

For me, participation in open source projects – particularly the ones I initiate myself – serves a very useful purpose as deliberate practice. While it may not be immediately obvious, I find the psychological structure of making my work public, combined with the ability to refactor and rewrite as I need to learn more, help me to get the most from the time I spend working on such projects.