Tuesday, 22 July 2008

The Language of Behavior

Software quality is directly proportional to the quality of communication that takes place between the business and the developers My mother researched our genealogy back several centuries and I’m just about as English as they come – so I decided to spell “Behavior” without a “u”.  That’s the correct way to spell it – at least it was before we changed it to please the French!  Plus it Googles better.

Why is this important?  Well, the spelling’s not.  But the language of behavior is.  Eric Evans in his book “Domain-Driven Design” coined the term “ubiquitous language” meaning that the domain model should form a language which means as much to the business as it does to the software developer.  Software quality is directly proportional to the quality of communication that takes place between the business and the developers – and speaking the same language is essential.  How the software behaves should be described in terms that have meaning to everyone.

Enter “Behaviour-Driven Development” (BDD) which takes “Test-Driven Development” (TDD) to the next level using the language from the “Domain-Driven Design” (DDD).  It’s the holy grail.  To be able to describe what an application is required to do, in the ubiquitous language of the domain, but in an executable format.

Developers hate testing.  They even hate the word “Test”.  Loads of developers just don’t get TDD. It’s because the language is wrong.  Take the T-word out of the equation and it suddenly makes more sense.  Replace it with the S-word.  Specification.  We’re going to specify what the application is going to do (using the vocabulary) in an executable format that will let us know when the specified behavior is broken.  Suddenly it all makes sense.

So in BDD we have the user story expressed in the following way:

As a <role>
I want <to do something>
So that <it benefits the business in this way>

Then the story can feed the specification using Scenarios:

With <this Scenario>:
Given <these preconditions>
When <the behavior is exercised>
Then <these post-conditions are valid>

Which is effectively the Arrange, Act and Assert (3-A’s) pattern ( Given == Arrange, When == Act, Then == Assert) for writing tests specifications.

And, don’t forget, the specification needs to be executable.  For this we would love to have a language enhancement – we actually need Spec# right now.  But we won’t get that for a while (although I encourage you to check it out, and petition Microsoft to get C# enhanced with DbC goodness).  So in the meantime, we need a framework.  In the .Net space several frameworks (NSpec, Behave#) came together to form NBehave.

Now you can write code like this:

[Theme("Account transfers and deposits")]
public class AccountSpecs
    public void Transfer_to_cash_account()
        Account savings = null;
        Account cash = null;

        var story = new Story("Transfer to cash account");

            .AsA("savings account holder")
            .IWant("to transfer money from my savings account")
            .SoThat("I can get cash easily from an ATM");

        story.WithScenario("Savings account is in credit")
            .Given("my savings account balance is", 100,
                 accountBalance => { savings = new Account(accountBalance); })
            .And("my cash account balance is", 10,
                 accountBalance => { cash = new Account(accountBalance); })
            .When("I transfer to cash account", 20,
                 transferAmount => savings.TransferTo(cash, transferAmount))
            .Then("my savings account balance should be", 80,
                 expectedBalance => savings.Balance.ShouldEqual(expectedBalance))
            .And("my cash account balance should be", 30,
                 expectedBalance => cash.Balance.ShouldEqual(expectedBalance))

            .Given("my savings account balance is", 400)
              .And("my cash account balance is", 100)
            .When("I transfer to cash account", 100)
            .Then("my savings account balance should be", 300)
              .And("my cash account balance should be", 200)

            .Given("my savings account balance is", 500)
              .And("my cash account balance is", 20)
            .When("I transfer to cash account", 30)
            .Then("my savings account balance should be", 470)
              .And("my cash account balance should be", 50);

        story.WithScenario("Savings account is overdrawn")
            .Given("my savings account balance is", -20)
              .And("my cash account balance is", 10)
            .When("I transfer to cash account", 20)
            .Then("my savings account balance should be", -20)
              .And("my cash account balance should be", 10);

And you can run that in a test runner like Gallio (which even has ReSharper plug-in).  Just like you would run your NUnit/MbUnit/xUnit tests.

Jimmy Bogard, one of the authors of NBehave, wrote a great post about writing stories using the latest version (0.3).

NBehave is young.  But I love the fluent interface.  And the caching of the delegates.  And the console runner outputs a formatted (more readable) specification that you can give to the business.  It makes for really readable specs.

What about the granularity of these specs?  There’s definitely more than one thing being asserted.  But they’re much more than tests.  They are unit tests specs and acceptance tests specs combined. They define the behavior and check that the software conforms to that behavior, at the story and scenario level.  That’s good enough for me.  I’d much rather have this explicit alignment with atomic units of behaviour (OK, the English spelling just looks better).

Also, it reduces the coupling between the behaviour specification and it’s implementation, which means you can alter the implementation (refactor) without having to change the tests specs.  At least not as much as you might with traditional TDD.

To me it brings a great perspective to software development.  I’ve always believed in unit tests and in TDD.  This is just better.  By far.

Monday, 14 July 2008

Trust the experts

Our home in Betty's BayWhat better way to while away a 12-hour day-flight than to add a blog entry.  I’m off to Cape Town (actually Betty’s Bay where we have a small holiday home) for a week as I’m in-between jobs.  I just spent 4 years at London Underground (not a terrorist movement as US Immigration once thought I belonged to!).  It was by far the most challenging and rewarding role in my career.  It was there that I learned the most about writing great software.

I discovered what’s important.  I’ve always paid attention to detail and that’s important.  I’ve always made sure that I know my languages and tools inside-out and that’s important.  Communication with the customer (and the team) has got to be right up there.  The most important thing, though, to help a team write the best software, has got to be trust.  Not just trusting each other in the team – I already understood that.  Not just trusting the customer and having her trust us – also understood.  What I learnt at LU was that our management has to trust us.  Total trust.  Especially when we’re delivering. And delivering quality. Regularly, on time and in budget.  (I promise that this post is not going to turn into a rant because I’m actually grateful that I’ve learned this now, and that I can pursue the rest of my career without ever having to work again in an environment where management don’t trust and respect software development teams.)

It’s incredibly hard for people that don’t get software to get software.  The corollary is also true – it’s incredibly hard to help people that don’t get software to understand what it is all about.  To them it’s just magic.  All they can see (if they’re interested) is what the software does.  Not what it is.  Or what it takes to create it.

We do have an incredibly powerful tool in our arsenal.  Being ¨Agile¨ is the only way I know of breaking down the divide between those that understand and those that don’t.  Although even being agile is not enough if you’re labouring under bad management.

Upward Spiral

The first 3 years at LU were like a dream.  We were getting more and more agile by the day.  Everybody was winning.  The business were getting exactly what they wanted.  When they wanted it.  The team was strong.  And happy.  And very productive.  I’m not saying we were perfect – that doesn’t happen – there’s always further to go than you’ve already come.  But the management were excellent – they believed in us and that was the key.

Downward Spiral

Then, a year ago, new management came in and took over.  By stealth.  Crony appointments for unqualified people who subsequently protect their positions using Mugabe-esque power tactics.  Tarring everyone with the lowest-common-denominator brush.  Simply because they don’t understand software and are scared (actually terrified) that everything will collapse in a heap if they trust anyone.  So don’t trust anyone, don’t let anyone have any responsibility or let them make any decisions.  Even if they’re the only ones qualified to do so.  Bind everyone up with rules, process and bureaucracy.  Watch them with a hawk’s eye.  Control them and they’ll never put a foot wrong.

Wrong, wrong, wrong! Trust them and let them fly.  Trust the experts.  They’ve spent more time and effort learning their trade than the management have theirs.  They know what they’re doing (most of the time!).  Engage with them and let them help you understand software.  Get the best people you can afford.  No, get better people than you can afford.  Let them be agile.  Remove the weight of process. Respect their knowledge and watch the results.  It takes brave management to do that.  But its the only way to get great software and to keep the best developers.