Perception of language

Darren and I had a chat about my article on arrogance. He said he didn’t like my “anti-pragmatic” stance.

I was confused. “But… I wasn’t anti-pragmatic. Was I? I said that idealists need to listen more to pragmatists. I parodied our idealistic attitudes and countered them with pragmatism. Why did my post seem anti-pragmatic to you?”

“Well,” he said, “you started talking about us (idealists) and them (pragmatists).” And that kind of talk led Darren (and others, we theorize) to an assumption that the us position is going to be defended against the them in the subsequent argument.

People see what they expect. I remember a television program in which two people carrying a door walked between a man who had stopped to ask a student for directions. While the door passed between them, the direction-seeker behind the door was switched to another man – not necessarily physically similar. I don’t remember exactly how many people didn’t notice the switch, but I remember it being surprising (like 50%).

So my post led Darren to expect a confrontational argument in which I backed my position as an idealist, and initially at least, that’s what he saw. (It wasn’t his only criticism, but it was the only one that I thought was brutally unfair. 🙂 )

Maybe this kind of use of language is part of the “perception of arrogance” problem. Nobody expects self-deprecation. Who builds up a position for themselves and then attacks it? I did, uncharacteristically, and at least one person didn’t notice.

We also talked about negative and polarising language; the use of terms such as right which implies wrong, and the battleground formed by us and them. There’s no logic to it. Arguments aren’t won or lost on logic alone, nor can people be persuaded by it, but it always surprises me when very logically-minded people misunderstand communication – and makes me wonder how often I misunderstand, too.

Posted in Uncategorized | 4 Comments

Procedural methods in OO code

A discussion on the Yahoo XP group regarding refactoring long methods into smaller ones coincided with me writing the code below. This is from my most recent test class, which is 180+ lines and growing:

    public void testThatRefundingTwoToysBoughtOnDifferentDaysDoesNotCauseError() throws Exception {

        goBackTwoDaysFromRealDate();
        String transactionRefA = buyToy();

        goBackOneDayFromRealDate();
        String transactionRefB = buyToy();

        goBackToRealDate();
        String refundTransactionRef = refundItems(transactionRefA , transactionRefB);

        verifyNoErrors(refundTransactionRef);
    }

I’m glad I did this, because now when I go back to it after finishing this quick post I’ll know exactly what I was doing. I don’t have to wade through the 180+ lines to find out which bits have the TODO comments in. Plus, when the next person comes to look at the weird configuration file I’m about to change, they’ll be able to tell from a glance at the code why I removed the lines I have. They can work with the change instead of around it.

This exercise made me realise that there seem to be a lot of very long tests around. In case it’s a prevalent thing and not just a statistical glitch, please let me beg on behalf of the campaign for legible tests – split ’em up! Make them readable. Your tests define the behaviour of your application. If you’re racing along in an Agile environment then they may well be the only documentation you have.

(Did you know that in JUnit you can write an abstract test class, and any tests in it will be called when the subclass test is run? You did? Did you know that you can also do it with behaviour classes in <plug>JBehave</plug>?)

Of course, one has to be careful when refactoring tests. It’s easy enough to tell if your test fails as a result of refactoring. It’s harder to see if it no longer tests the same thing as before, and passes regardless. For instance, when writing abstract JUnit test classes, be careful not to put tset or should instead of test at the beginning of the method, unless you have a particular fondness for the word “Doh!”.

Update: Time travel is now parameterized too:

    public void testThatRefundingTwoToysBoughtOnDifferentDaysDoesNotCauseError() throws Exception {

        goBackInTime(2);
        String transactionRefA = buyToy();

        goBackInTime(1);
        String transactionRefB = buyToy();

        goBackInTime(0);
        String refundTransactionRef = refundItems(transactionRefA , transactionRefB);

        verifyNoErrors(refundTransactionRef);
    }

Thanks to the XP group for hints and tips on how to make vaguely similar bits of code turn into almost identical bits of code (Summary: put all the similar stuff together and move the dissimilar stuff somewhere else.)

Posted in Uncategorized | Leave a comment

Noise out of proportion, and random things out of context

I spoke to some of my colleagues back in London and was reliably informed (again) that the ratio of idealists to pragmatists amongst them is in fact lower than I made out in my last post. We did agree, though, that it’s the idealists making most of the noise.

New things from last night’s conversation, to be investigated later:

  • Domain-specific languages. This (briefly and inaccurately) is what happens if you notice that something is changing a lot in code, and move those changes to a configuration file. The file itself is then a form of language. (A better definition can be found here).
  • The database problem: part 1. If you’ve got several client versions in production, the server database has to be backwards compatible. This makes it hard to change, which can make the domain model hard to change too. What solutions are there for getting round this problem?
  • The database problem: part 2. A grid which relies on a central database can’t scale as well as we’d like. The database forms a bottleneck. What solutions are there for getting round this problem? (And what kind of things require a central database?)
  • Zen and the Art of Motorcycle Maintenance. I only got halfway through this last time I tried, about three years ago. Now I know a little more about philosophy and the twisted nature of the human mind. Time to try again?
Posted in Uncategorized | 24 Comments

Arrogance and Thoughtworks – in the same sentence? Surely not…

arrogant
adj.

  1. Having or displaying a sense of overbearing self-worth or self-importance.
  2. Marked by or arising from a feeling or assumption of one’s superiority toward others: an arrogant contempt for the weak.

Thank you, dictionary.com.

“Do you know,” said Roy, “that eighty percent of people who’ve come into contact with Thoughtworkers think that we’re arrogant?”

“Really?” I asked. “How many Thoughtworkers think Thoughtworkers are arrogant?”

“About ninety percent,” he conceded.

We both agreed that this was odd, since TWers are amongst the least arrogant people I know. We are, in general, always interested in learning new things; ready to be told that there’s a better way than our own; never fooled into thinking that we know everything; open to critisism. So why do Thoughtworkers so often come across as arrogant?

As someone who gets mistakenly labelled as arrogant all the time, I’m obviously the best person to answer this question. So I have.

A sense of self-worth

There’s a difference between self-worth and self-importance. Self-importance is delusional; it suggests that the team, the project, the company or the world will fall apart without you. Perhaps that happens in an environment where knowledge is closely guarded, but most TWers love new things and hate to be stuck on the same project for months. I think we’re more likely to give away our knowledge; to ensure that someone else can take over our role, and to make ourselves as redundant as possible. I don’t think that we regard ourselves as important, or even want to be.

We do, however, have a sense of self-worth which is greater than that of your average IT bod. We know that our opinions matter, that we can make a difference, and that we all have responsibility for everything (thank you, Collective Code Ownership, management transparency and a flat hierarchical structure). We also know that this is true of everyone else in the company. That kind of mutual respect makes for a great place to work. The problem is that the enthusiasm generated by our environment often translates into “Look! Our world is so great! You should do this too!” (This is also the traditional TW greeting given to newcomers to the company, along with a garland of books and articles detailing the exact architecture required to build the better world.)

One of the problems with suggesting a better way is that it casts a reflection of something worse; something wrong. In most of the world, doing something wrong equates to a certain level of punishment, be it in lower salaries, stressful emails and memos from on high, rehabilitative courses or plain sacking. So until the world gets rid of the blame culture, there will always be people who aren’t prepared to be told that they’re wrong – especially if no one is interested in the stuff they’re doing right.

A feeling of superiority

Is our way really better? Which companies, exactly, are we superior to? Which projects?

There’s still a debate out there as to whether Agile is useful on, say, large-scale projects involving > 20 people or mission critical applications like aeroplane flight controls, and I have my own gut feelings about its practical application to legacy code.

How do you know, before you’ve listened, that a company might not be doing some things right already?

I’m pairing up to run the Agile induction course tomorrow and I’m very nervous about it. One of my colleagues here told me, “Don’t worry. Everyone started Agile somewhere; they worked out that there was a better way and played it by ear until they got it right.” And there are people playing around out there. Agile-like practices which I’ve seen outside of Agile projects include:

  • test-first design (less disciplined than test-driven, but it still works)
  • self-documenting code
  • collaborative code ownership (a natural practice for any team disinclined to blame ?)
  • feature-driven design (similar to story-driven design)
  • a zero-overtime policy (at 37.5 hours, even better than the 40 hour week)
  • pairing
  • stand-up meetings
  • frequent code integration

I don’t think any of the companies I’ve seen doing these things are familiar with the concepts of Agile or Extreme Programming. They were just doing these things because they worked; because there were a few bright sparks running things who worked out how to prevent the problems they’d encountered on previous projects. The founders of the Agile movement went a little further, but they all started somewhere too.

I’d swear that one company I worked with has a secret Agile practitioner converting the way they work. “Wouldn’t it be better, instead of writing a method this way, to break it up into reusable chunks? Wouldn’t it be great if this variable was renamed so we knew what it meant? How about we inject this via an interface so we can put that functionality into a new class? What if we have low-level tests for our code, so we know if it fails before we send it off to our poor beleaguered test team? What happens if we integrate more regularly so that the merges become easier and don’t break everything quite so often?”

Thinking back on his approach, I am once again filled with real respect for this cunning rebel. He knew he was right – of course he was! – but he asked questions to make other people do the hard work of realising it; by which time, of course, they were right too. I never once heard him say, “Listen! Look!”, but I bet he sits back at his desk every day with the smuggest smile on his face.

Guess what? He doesn’t work for Thoughtworks. I really, really want to meet the people like this who do. Stop being the quiet voice, whoever you are.

Contempt for the weak

Ah. See, this is the problem; I don’t think it’s weakness we’re contemptuous of. I suspect it’s pragmatism.

Pragmatists are prepared to compromise their ideals in order to get a job done. Most Thoughtworkers are idealists, and worse; some of us are evangelists who are convinced that we can change the world. Here are three idealist thoughts on why people might practice pragmatism, particularly with respect to Agile evangelism:

  • Not wanting to upset people by telling them that there’s a better way than theirs
  • Pandering to a team’s inability to absorb a number of changes at once
  • Denial of responsibility for the problems caused by poor procedure.

Or, as the pragmatist might phrase them:

  • Tact
  • Consideration, and respect for the learning curve
  • Recognition that not everyone shares the same ideals, and that there’s more than one way to skin a cat.

From an extreme idealist’s point of view, failure to follow ideals is a weakness. If there’s some reason why an ideal can’t be met, then that needs changing too. What – too many changes at once? Courage! Courage! It’ll all work out in the end. Why can’t you trust us? Why can’t you see how right we are? Why won’t you bet your time, your career and your company’s money on us being so very, very right?

I’m a self-confessed idealist, so I find it hard to see things from a pragmatist’s point of view; but I’ve tried, and will probably write again about it in the future. One day I may even practice a little pragmatism myself. The point I’m trying to make is that pragmatism isn’t a weakness; it’s just a different way of approaching the problem. Idealists have a destination. We plot a crows-flight path and try to follow it as closely as possible (and the evangelist will try to drive everyone else that way too). Pragmatists just want to get there quickly. If there’s a traffic jam on the motorway then they’ll take the back roads; otherwise, the most proven route with the least effort wins out.

Idealists build new roads, and will one day invent the Personal Flying Vehicle to eliminate the necessity for new roads at all. Pragmatists widen the existing roads, and will one day comprise the majority of Personal Flying Vehicle customers.

Clay Shirky’s article on whether Wikipedia is a good thing (or the part which Carlos summarised nicely) gave me another of those beautiful moments of epiphany. There’s nothing wrong with radial or cartesian people; with pragmatists or idealists. The world needs both. Maybe it’s time for us idealists to start listening to the pragmatist’s point of view.

Humility

humbleness
n

  1. the state of being humble and unimportant
  2. a humble feeling; “he was filled with humility at the sight of the Pope”
  3. a disposition to be humble; a lack of false pride

A common Thoughtworker expression, albeit paraphrased, is that each of us looks back on our work six months ago with astonishment for how poorly it was done – and correspondingly, though fewer mention it, a sense of accomplishment when we think of how far we’ve come.

Perhaps that’s the problem with my humility and that of other Thoughtworkers too. It always comes with a sense of glory. Every realisation that we’ve done something wrong comes as a result of learning a better way, and we love that feeling; not the humility, but the epiphany that accompanies it; the ‘Papal visit’ of Agile evangelism. Humbleness is there, I promise. If you ever want to see humility on a Thoughtworker’s face, just ask him, “What’s the most stupid thing you’ve ever done?” and watch his expression change as he mentally runs down the list.

We have no egos; at least, not ones that care about their appearance. Our sense of self-worth is collective, not individual. Our idealism comes out of a desire to do right, not to be right. Sometimes it gets mistaken for arrogance, but it isn’t. Really. Why anyone would think that, I have no idea.

Disclaimer

I’ve never named Thoughtworks in my blog before, mostly because I’ve only been here for six months, and partly because I wasn’t sure they’d want to be associated with my ramblings. I’m not an expert on Thoughtworkers, but I am one. I’ve spoken to a lot of them. I am not a psychologist, a psychiatrist or in any way associated with the dissection of character, except as a writer. I have my fair share of both arrogance and humility. One is louder than the other. This piece is not intended as an apology or an excuse for anything I may have written previously.

I was asked to write on arrogance at Thoughtworks, and have tried to do so thoughtfully. It’s not an instruction manual. It’s not perfect. I have generalised horribly about various categories of people, especially my colleagues, ex-colleagues and client staff. Some of you are less arrogant than others. I love working with you all.

This post represents my personal views, etc., and hasn’t even been read by the TW management at the time of posting, let alone authorised.

Now you’ve read the disclaimer, if you’re still offended by this post, please let me know. I’m keeping score.

Liz.

Posted in Uncategorized | 33 Comments

A quick chat with a Rubyist

I’ve not touched Ruby yet, but I’m insatiably curious, so I talked to Darren about it.

As far as I can work out, dynamic languages in general are fantastic if you’re running Test Driven Design; because it’s not the compiler that tells you you’re wrong, it’s the tests. (I’ve never tried this with a dynamic language, but am looking forward to the experience.)

I have a bit of a problem with this idea, though. As much as I like to go on about “the right way”, in practice I’ve not yet seen a project where all the developers write tests for absolutely everything, however much they might like to. The temptation to “just hack that bit of code” seems to be too much. I think this is particularly true of project tools; those little scripts which lend themselves nicely to Perl or Ruby and which aren’t really part of the code base.

Does Ruby tend to encourage people to write tests for everything? Darren thinks not. I’ve certainly hacked a few Perl scripts together in the past; things which had ten line comments for one strange regular expression, or little scripts which made perfect sense to me then, but I couldn’t tell you what they did or how they worked today. They always grow; have you noticed that? I like to think I’m a bit more disciplined now than I used to be, but the idea of thousands of developers out there with another language that lends itself to hacking makes me uncomfortable. It’s like seeing a good friend try on a dress, asking, “Does this make me look fat?” and trying to work out how to tell her that really, it’s not the fault of the dress. Imagine the expression on my face. It’s the same one I’m wearing now (the expression, not the dress).

It’s not Ruby’s fault; I’m sure it’s a great language. I believe, though, that there’s another way to encourage people into the golden path of TDD, even full-on Agile. Ruby’s a relatively new language*, and from this outsider’s point of view, it looks as though it’s gaining a culture and a following all of its own.

Is TDD part of that culture? Do the manuals, forums, etc. for Ruby say, “If you use this language, you should consider reading more about Test Driven Design”?

Just curious… and lazy…

I have vague, unformed visions of a monster language which is absolutely bound to definitions and tests for the behaviour of each class. I have even more vague ideas of how to implement that. I have a better idea of how horribly unwieldy it might be. Back to JBehave…

Update: Thanks to commenters and to Steven, who wrote this illuminating post in response. I think I’m starting to grasp the “Rails” concept of Ruby on Rails – it’s a web development framework with integrated testing (thanks, Steven). Will have to get round to practicing this at some point. If nothing else, I’d love to get a feel for the speed of the TDD / dynamic language cycle.

It’s good to see a bunch of people being so enthusiastic about their work. Hope for the future.

* I’m told that my perception of Ruby as a new language is wrong; it’s been around for as long as Java, and unit testing is built into the standard library. Sweet.

Posted in Uncategorized | 6 Comments

What’s missing?

Last week, Alan pointed me towards Dale Emery’s post on <a href="http://www.dhemery.com/cwd/2003/06/the_value_question.html”>the value question. Reading it made me think a lot about several things which I’m trying to accomplish; today, tomorrow, and with my life in general. It’s been an interesting week. Along with the General Election here in the UK we also had local elections, which took over my house for a little while, so I’ve also been thinking about the government, our local councillors, world politics and what the leaders of the world are trying to achieve.

While this is going on, I’m also thinking about becoming an Agile Coach; a goal for the future for which I’ve still got a way to go. It started me thinking about why Agile methodologies came about in the first place. And, as happens when you start thinking too much on a Friday afternoon, some parallels between software development, my life, my world and plot devices I’m trying to work over for a couple of stories started to fester in my head. I realised that in every plot I’ve read, a combination of just a few things were conspiring to make up that curse which the Chinese call “interesting times”.

Dale’s Value Question asks, “If you had that, what would it do for you?”

What would a little imagination, a little courage, a little more communication do for me? For the world? If I had a little more courage, would I send out those stories still sitting at the bottom of my hard drive? If I had a little more imagination, and talked to people some more, would I finally get my head round service-oriented architecture? Would a little imagination and courage open the north of England for development, and stop the government trying to put still more houses in our very crowded south-east? Foresight is an offshoot of imagination – can’t they see that the rail network won’t take any more commuters? Why do people lust after power and money? If the power-hungry talked to people a little more; if they had the courage to deal with uncertainty in their future, and the imagination to see that you don’t always have to be in charge for things to work out, would they worry less about that next ten million dollars? If Britain and the US together could convince Israel and Palestine that there really is a solution out there somewhere, would they be able to imagine living together in peace?

If I focus on the things which are missing, I wondered, will it be easier to manage my life? Or come up with plot devices for that next chapter? Or inspire other people to talk, to believe, to imagine?

I tried to find orthogonal values, ones which don’t overlap, to describe the problems I and other people around the world are facing. (Read Dale’s post – he has a very good example of reducing a problem. I’ve taken it a little further, which may not be practical for everyone but does help me focus.) I came up with three things that every problem I could think of could be reduced to – a lack of communication, a lack of courage and a lack of imagination (or foresight, though that doesn’t cover all the problems I thought of). There may be other orthogonal descriptions of problems in the world, but those three things struck me as being simple and sad, because they look as though they should be so easy to resolve.

So I wrote them down, so I’d remember, and because some people might find it inspiring, or interesting, or thought-provoking. I also added a fourth; the reason why I’m not a published author yet, I’m not an Agile Coach yet, I didn’t get to the gym this weekend and I didn’t write down all these thoughts on Friday afternoon – lack of time. It’s less orthogonal than the other three. I think anyone with time on their hands can use it to become a better communicator, to learn how to deal with uncertainty or at least see how uncertainty resolves, and to realise that there’s so much out there to learn that half the time all you can do is make a best guess.

Posted in Uncategorized | 3 Comments

Here’s another theory

All problems, from wars to software bugs, are caused by a combination of the following:

  1. lack of communication
  2. lack of courage
  3. lack of imagination
  4. lack of time.

It’s arguable that the first three are products of the last.

Posted in Uncategorized | 16 Comments

More thoughts on Agile documentation

Matt Ryall responded to my post on documentation with some suggestions for making it easier. I finally persuaded my brain to give up some of the thoughts that it didn’t like (because they’d result in doing documentation). This isn’t particularly structured, just a few random ideas and concerns.

Stable code

What happens when part of the system is working perfectly, the customer is very happy with it and there are no changes likely in the future? No one is working on the code any more. No new developers are being introduced to the code base through pairing. Knowledge is slowly being lost from the system. Is there any way to identify code that’s reached this state? Are there any easy ways to produce a quick, high-level overview of the code?

If there are big sections of the code base which are stable, should they perhaps be separate sub-projects? Can a customer sign off sections of the project before the whole thing is finished? eg: an administration console, a look-and-feel or gui component palette, a logger, or a related standalone application?

Splitting a project up this way might help to reduce build times and complexity. The code would, however, have to be documented. For a library that may mean javadocs and clear code naming. For an application, that may mean a user manual.

Wikis

Could a Wiki be scripted in some way so that out-of-date documentation is flagged? Do we need some kind of agile methodology for stopping Wikis from getting too big, too complex, and duplicating information? I can’t find anything I’m looking for on ours, because the bits and pieces which people put there three years ago are still there, and hardly any of it is relevant any more.

    Good things to put on Wikis include:

  • details of commonly used test data
  • TCP IP numbers of servers, etc.
  • Links to useful tech sites, eg: J2SE 1.4.2, JMock, Hibernate, etc.
  • VM parameters (we have about 20 of these and I don’t think they’re documented anywhere!)
  • HowTos
  • Reasons for choice, eg: “Why we switched to Hibernate”
  • A map showing the local pubs, bus stops etc.
    Bad things to put on Wikis include:

  • CRs, bug reports, etc. – there are better ways of tracking important bugs
  • Anything which people have to read regularly (use email updates; Wikis are passive)
  • Notes for new joiners (this should be emailed too, if only because people don’t like to email inaccuracies and out-of-date information, so it might actually stay relevant)
  • Anything which requires you to go through 3 other unrelated Wiki pages to find it
  • Lists of people on the project, half of whom left six months ago
  • Invitations to a special event in April 2003.

The flashing red light

My experience tells me that if there isn’t some big flashing light that goes off when something’s wrong, it won’t get fixed. For code, we have the red bar. What do we have for documentation? Matt mentioned using references to code names, etc., so that they are automatically updated.

Make documentation part of the build process, eg: if you’re using Javadocs and linking from one piece of code to another, run a script which checks for broken links as part of the build.

Posted in Uncategorized | 2 Comments

Just for kicks, some more sheep…

Here’s a quick test for the fence from my last post. My customer wants a fence which allows sheep to graze in a field, and prevents sheep from wandering outside of the field.

public class FenceTest extends TestCase {

    public void testShouldAllowSheepToGrazeInField() {
    
        Field field = new Field(3, 4);
        Sheep sheep = new Sheep();
    	
        Fence fence = new Fence(field);
    	
        boolean sheepGrazes = fence.sheepGrazes(sheep, 3, 3);
        assertTrue(sheepGrazes);
    }
    
    public void testShouldPreventSheepFromWanderingOutsideField() {
    	
        Field field = new Field(3, 4);
        Sheep sheep = new Sheep();
    	
        Fence fence = new Fence(field);
    	
        boolean sheepGrazes = fence.sheepGrazes(sheep, 3, 5);
        assertFalse(sheepGrazes); 	
    }
}

It’s easy to write code which implements this, so imagine that I’ve done it. Hurrah! Green bar. That was easy.

Now supposing that my customer wants to define the strength of my fence, so that it gives way if a really strong sheep comes along. (This is how things like Sims get started!) Here goes:


    public void testShouldAllowStrongSheepToBreakFenceAndWanderOutsideOfField() {

        Field field = new Field(3, 4)
        Sheep strongSheep = new Ram();

        Fence fence = new Fence(field);

        boolean strongSheepGrazes = fence.sheepGrazes(strongSheep, 3, 5);
        assertTrue(strongSheepGrazes);
    }

Another easily implemented test. Bang! Green bar. The customer is very happy with the way in which the Ram can escape the clutches of the fence and graze beyond the boundary of the field.

But wait! My pair has spotted something I missed. He speaks briefly to the customer about the definition of ‘break the fence’, then writes this excellent failing test:

    public void testShouldAllowAnySheepToWanderOnceFenceBroken() {

        Field field = new Field(3, 4)
        Sheep weakSheep = new Lamb();
        Sheep strongSheep = new Ram();

        Fence fence = new Fence(field);

        fence.sheepGrazes(strongSheep, 3, 5); // result covered by other test

        boolean weakSheepGrazes = fence.sheepGrazes(weakSheep, 6, 6);
        assertTrue(weakSheepGrazes);
    }

So now we implement a “broken” state in the fence, to allow sheep to graze. We know that the fence is still whole when sheep are originally put into it, because the second test still passes. We should probably rename the second test to testShouldPreventSheepFromWanderingOutsideFieldWhenUnbroken. Now no one will misinterpret the “documentation” provided by the test names, and the code will ensure that anyone who, say, puts Horses which can leap over the fence into the same field, doesn’t accidentally cause the Rams to start leaping over the fences too.

(In the real world I would mock the sheep out so that the fence’s behaviour was independent of the sheep. But you get the picture.)

Posted in Uncategorized | Leave a comment

Test (or Behaviour) Driven Design in lieu of documentation

Jim and his colleagues (hope you don’t mind me using you as an example) write documentation as the reference point to code. Then, one group of people write the tests, and one group of people implement the functionality, both working from the same set of documents. They then run the functionality against the tests to see if they’ve done it correctly (or if perhaps the documentation is wrong).

(If the documentation is wrong, then documentation, test and code must all need rewriting. Do you have to wait for the documentation to be produced before the two teams of testers and coders can get on with the next bit?)

With Test Driven Design you write tests first, thinking all the time of the behaviour you want to achieve, then you write the functionality to pass the tests. So it doesn’t matter who writes the tests and who writes the functionality (and pairing helps you to avoid any bad design decisions that might otherwise get made).

The tests form the reference point. Because the full test suite is run every time anyone changes the build (about once an hour) you know very quickly if something is broken. Then, the person who breaks the build can look at the ‘broken’ code and tests and decide whether they’ve actually caused a bug, or whether the code should behave in a different way to the way it’s defined in the tests (usually this happens when a customer decides to change the requirements, or a bug is found because no one thought that a user would ever do something that obviously silly, even though they always do). The story cards provided by the customer also form a reference point, but if you don’t have a story card in your hand which directly contradicts the code behaviour, you know that the stories from previous iterations are still valid and still working.

When a requirement changes, or a bug is found, we write tests which fail, to prove that the software no longer does what we want it to. Then we change the code so that the tests pass again. There’s an excellent form of pair TDD called “Ping-pong programming” in which coder A writes a failing test which coder B must make pass, then coder B writes a failing test for coder A to implement, etc. The two coders sit together to do this. It’s a lot of fun and results in code that does as little as it possibly can to get the job done (ie: minimalist, clean, and very legible if me* and people like me** have beaten them over the head often enough).

Documentation makes it harder to change code, and is one of the reasons for the exponential cost-of-change curve seen on top-down projects. If your code is defined by its tests, then you can do whatever you like to them – refactor, rename, remove – and know that you haven’t broken any existing functionality. Five years down the line, the tests will tell you what the code ought to do, as well as giving you confidence that it still does it.

Oh, yeah – I think I’ve written a single one-line comment this week, and no documentation. You can tell what my code does because my tests say things like “testShouldAllowSheepToGrazeInTheField” and “testShouldPreventSheepFromWanderingOutsideField”. There are parsers around which will go through tests like this and produce documentation for you, eg:

Class Fence:
– should allow sheep to graze in the field
– should prevent sheep from wandering outside field

Class ElectricFence*** extends Fence:
– should dissuade sheep from breaking this fence

* Should be “I and people like me”. Agile and English have this in common: it takes real effort to get it right, even the strictest proponents aren’t perfect, and when you do get it right, it can feel very strange.

** By people like me I mean people who have been beaten over the head regarding code legibility by people like me, repeatedly, until they got it. Like me.

**My ElectricFenceTest class extends the FenceTest class, so ElectricFence still maintains the behaviour of a Fence. Nothing to teach about TDD there; I just love geeky things like that.

Posted in Uncategorized | 2 Comments