unclebob does the prime factor kata

update 2009-11-12: There is an updated version here

unclebob doing the prime factor kata:

BDD is not about testing

When talking to people about BDD and my lame example using Paris Hilton, then I got the question “it was really interesting reading about Paris Hiliton .. but what is BDD really about?.

The central insight of BDD is that TDD is really computer aided specifications of the executable behaviour of your system. BDD tries to express this using a Domain Specific language.

Back in 2006 , Dave Astels described how to ascend from the focus on 1-1 testing of production code to use the test proces as a way to describe the way you want your system to behave.

In the video Dave makes the valid point that “The words you use shape how you think”. So we should go away from thinking about “testing” constantly to think about describing how you want your system to work.

So to me – BDD sounds like a kickstart to be productive in TDD – and do it well from the start. So if you are starting out on TDD , you should really start out doing BDD.

Dave walks through some examples using rspec in ruby. I am currently using jspec

Paris Hilton and Behaviour Driven Development

Recently, I have been giving Behaviour Driven Development some thought.

Let’s take a an example of how to develop and test a music video search and storage system. A traditional way of developing this would require formulating a object oriented system architecture, thinking about streaming and metadata enabled search. The system architecture could consist of a well chosen database server, a streaming server and a metadata enabled search engine – combining these technologies with a modern UI and encapsulating theme in carefully designed object oriented structures. During all these important choices , and all during development we would make sure to write tests before we write a single line of code.

All these things put together would lead to a well thought out system architecture , but all the effort put into the system architecture can be in vain – if we don’t have a solid business understanding of what a video storage system should do. What will the users expect?

While browsing on facebook this other day I found the “The Paris Hilton & Jacques Derrida Appreciation Society” – this group explores the connections between the works of Paris Hilton and Jacques Derrida. When we deconstruct the “pretty blonde” facade of Paris Hilton, then you can actually find some deep insights. Take “Nothing in this world” for instance:

Take the phrase “when you are with somebody else, that’s me in your eye”. There is the obvious interpretation of the sentence . But thinking about that sentence also let’s you reflect on the real meaning . When you look at Paris Hilton in this video, what do you see? Do you see the pretty blonde or the millionaire , hard working young girl . In this video I am seeing the image of the pretty blonde – but I am also thinking about the millions of dollars she is earning portraying herself in this way. So in a sense – I am reading the original message out of context. I am admiring what Paris Hilton in some other way than she intended – the original meaning of the words seem to have disappeared – but my understanding of the sentence is more useful to me. I wish I could do what Paris Hilton does – but in a way that would make sense in my world .

The producers of the “Nothing in this world” video are not likely to convey information about the business empire of Paris Hilton in the metadata supplied for the video. So a system formulated as a “video storage system” would not let me exploit the information I found in the facebook group.

BDD introduces the use of a Domain Specific language to express the users expectations in a manner more directly focused on the behavioural aspects of the system. This lifts the clouds from the system aspects and focuses on intent.

A better way to formulate my expectations for the system would be:

Describe the music video storage system:
  I should be able to search for videos using metadata
  it should play videos  in my browser
  I should be able to query facebook for information about it
  

If I had those expectations formulated to me , then I would choose to implement this system as a mashup between youtube and facebook as a facebook application. This would be a radically different system architecture than the one describe above.

Furthermore , by leveraging one of the several BDD test frameworks available, then the expectations could be formulated in way that can be used as tests.

A wave is coming

Last week I attended a  day of outstanding geek fun . At the Google wave hackathon I had the chance to sink my teeth into the Google wave API after seeing presentations on gwt and google wave  by Tommy Pedersen and a presentation on wave gadgets by  Joakim Recht.

After a couple of hours of presentations and brainstorming  we started hacking.  I teamed up with  skakanka to experiment with sending the contents of a wave to a Proof of concept Document storage system . But we ended up doing a simple Echo Bot (but hey! we illustrated how to extract content from a wavelet and send it somewhere).

I brought a mac and used the Google eclipse plugin for galileo for coding. It helped that I allready had a Google app engine account from some earlier experiments – but I spent some time learning the different key combinations on the mac – it was great fun though (and now I know how to use eclipse on  a mac!). Deploying on google app engine is as simple as pressing a button in eclipse (I also tried using som ant tasks in my earlier experiments).

We managed to have a google wave running sometime before lunch – so it is very easy to get a basic understanding what a wave bot is all about. (You could think of it as an ircbot on steroids ! )

The overall idea of building a google wave bot is to listen to incoming events defined in the protocol. Let’s say we want to perform something when somebody enters the wave or write something – then we can define the capabilities like this:




0.0.4





Then the robot should act on the defined events in a manner similar to this :


@Override
public void processEvents(RobotMessageBundle robotMessageBundle) {
Wavelet wavelet = robotMessageBundle.getWavelet();
String rootText = wavelet.getRootBlip().getDocument().getText();
for ( Event e: robotMessageBundle.getEvents()){
Blip b= e.getBlip();
String text= e.getBlip().getDocument().getText();
if (e.getType().equals(EventType.BLIP_SUBMITTED)){
e.getBlip().getDocument().append( makeEcho(text));
}
}
}

The Wave client api offers something like the DOM api for the xml being sent back and forth. During the hackathon I learnt that there is no way to ask for the contents of the entire wave from a single blip – so it will require some thinking to save the entire contents of the wave – but it should be doable.

Sometime during the afternoon things started to slow down on the wave test server. I noticed that some of the other guys doing a multiuser interactive drawing gadget for wave. It looked like they recorded a delta to send every time the mouse moved! This made me want to look a bit under “the hood”:

Sounds like the team are handling the multiuser issues using “operational transforms” . Maybe they could somehow ‘batch’ deltas from interactive gadgets ? I have yet to fully understand how “operational transforms” work  – but it sounds like an exciting challenge to make this work on a large scale!

openlayers 2.8 supports WFS-T

if you are in a organisation where you store data with geographical information associated with it , then you have the option of sharing your data using the following standards specified by OGC:

One way to leverage these standards is to use the geoserver project for data storage and the openlayers project web for showing and editing maps.update 2009-09-03: When integrating with the extjs framework , then it is worth using the geoext project.

An example snippet from geoserver shows the use of WFS-T for inserting geometric data with associated metadata for an alley in Tasmania. I’ll just bring it here:


xmlns:wfs="http://www.opengis.net/wfs"
xmlns:topp="http://www.openplans.org/topp"
xmlns:gml="http://www.opengis.net/gml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd http://www.openplans.org/topp http://localhost:8080/geoserver/wfs/DescribeFeatureType?typename=topp:tasmania_roads">







494475.71056415,5433016.8189323 494982.70115662,5435041.95096618





alley



Note that oracle has a well supported ways of extracting GML from spatial datatypes if you need to construct the wfs transactions yourself ( oracle locator )

At the first glance wfs can seem a bit complicated. Luckily openlayers has nice wrappings for it that is easily accessed from code as shown in one of their examples running here :


map = new OpenLayers.Map('map');
var wms = new OpenLayers.Layer.WMS(
"State",
"http://sigma.openplans.org/geoserver/wms",
{layers: 'topp:tasmania_state_boundaries'}
);
wfs = new OpenLayers.Layer.WFS(
"Cities",
"http://sigma.openplans.org/geoserver/wfs",
{typename: 'topp:tasmania_cities'},
{
typename: "tasmania_cities",
featureNS: "http://www.openplans.org/topp",
extractAttributes: false,
commitReport: function(str) {
OpenLayers.Console.log(str);
}
}
)
map.addLayers([wms, wfs]);
var panel = new OpenLayers.Control.Panel({
displayClass: "olControlEditingToolbar"
});

var draw = new OpenLayers.Control.DrawFeature(
wfs, OpenLayers.Handler.Point,
{
handlerOptions: {freehand: false, multi: true},
displayClass: "olControlDrawFeaturePoint"
}
)
var save = new OpenLayers.Control.Button({
trigger: OpenLayers.Function.bind(wfs.commit, wfs),
displayClass: "olControlSaveFeatures"
});
panel.addControls([
new OpenLayers.Control.Navigation(),
save, draw
]);
map.addControl(panel);
map.zoomToExtent(new OpenLayers.Bounds(140.64,-44.42,151.89,-38.80));
}