Archive for the ‘XP, Agile, Lean’ Category

ReSpect RSpec

{Monday, May 21st, 2007}

What is Behavior Driven Development (BDD)?

According to behaviour-driven.org BDD was born from NLP experiments (astonishingly, nlp.com mention NLP and hypnosis in the one sentence!).
It is a combination of TDD and DDD. Here are some of my attempts at describing BDD:

A process for describing the behavior of a system that is understood by both technologists and non-technologists.

DDD applied to the domain of TDD.

The concept of a ‘vocabulary for describing behavior’ is at its core, but interestingly the behavior-driven site falls short of defining the vocabulary (note the incomplete links at the base of this page).
BDD is strongly linked to TDD as tests are often used to describe the features, or behaviors, of a system. Consequently, part of BDD involves writing tests using the vocabulary.

Enter RSpec

That’s the driving principle behind RSpec. Test::Unit is perfectly fine for defining tests, but it doesn’t employ a BDD vocabulary.
RSpec does, and it throws in a side order of Mock and Stub support often needed for TDD. As it happens this support is virtually identical to that provided by Mocha.
Take your pick, the support both provide is particularly cool as you can Mock and Stub methods of any object, sure you can create Mock and Stub objects (in a fashion that I’ve been used to with EasyMock and JMock) but the object doesn’t have to be a Mock or Stub in order to Mock or Stub a method invocation.
To highlight this here’s an RSpec demonstration applied to a banking model;

  describe Account do

    before(:all) do
     @@amount = 100
    end    

    before(:each) do
      @account = Account.new
    end

    it 'should withdraw cash via a Transaction' do
      Transaction.should_receive(:deduct).with(@account, @@amount)

      @account.withdraw @@amount
    end

    it 'should log unsuccessful operation when withdraw is unsuccessful' do
      Transaction.should_receive(:deduct).with(@account, @@amount).and_raise(InsufficientFundsException)

      @account.should_receive(:log_outcome).with(:unsuccessful)      

      @account.withdraw(@@amount).should_raise(InsufficientFundsException)
    end

  end

Pretty cool huh?! This mocks two methods in a manner that can’t be easily repeated with Java:

  • A class method, Transaction.deduct
  • An instance method of a real object, @account.log_outcome

Take a look at the recently tweaked documentation on the RSpec site for info on it’s other features (like partial argument matches), and more generally its implementation of a BDD vocabulary.

Why use RSpec?

One of my initial encounters with RSpec was via a blog critising BDD that goes so far as to suggest RSpec is pronounced ‘arse peck’, so I’ve been skeptical from early on. I have been particularly cosy with XUnit tests, a mock framework and consistent test method naming conventions as a way of specifying behaviors, so I didn’t feel the urge to change. Test::Unit and Mocha can pretty much yield the same result - what did I have to gain?

Still, this ol’ school approach requires some discipline and custromizations to read like a BDD vocabulary. RSpec, on the other hand, encourages codification of tests in a consistent BDD vocabulary. But hey, if you don’t intend on using the vocabulary for communications between roles (and that’s a substantial change) your missing the major benefits of BDD - so why bother?

Nonetheless, it’s worthy of consideration.

With its subtle shift in the XUnit language I believe it produces more readable tests. That coupled with its nice mock and stub support and the potential benefits of a shared language for describing behavior - the pro’s start outweighing the con’s.

Parting Thoughts

I’ve read some BDD proponents claim they sought out BDD as a solution to tests that are tightly coupled to source, hindering refactoring and causing a maintenance burden.
I fail to see how BDD helps here; this is a natural consequence of writing unit tests. For tests to do their thing, an API under test must be invoked - you can’t avoid that. If you change that API; surprise, you’ve got to change your unit tests! If you’re suffering this affliction maybe you should test against an API few layers up, like HTTP. Personally though I’d be blind without my unit tests, at a minimum they aid design and verify correctness.

Paying Homage to DDD

{Monday, April 23rd, 2007}

I’ve read Domain-Driven Design (DDD) a couple of times now and consider it the most influential book on the way I develop software. But I’ve yet to blog about it. It’s time to change that.

Firstly, serious developers and analysts simply must read this book. It’s the sort of book I’d demand be read if I owned a software organization, though (being generous) around half of the book is applicable to Analysts.

Before I read DDD the concept of a Domain Model was somewhat fuzzy, even after reading Patterns of Enterprise Application Architecture. So often I’d seen ‘Domain Models’ purely holding state. I’d joined teams late in the game that had developed ‘intelligent’ Domain Models, but how they got there was a mystery. Questions like:

  • Why had this domain concept become a class?
  • Why apply this pattern in the domain layer?
  • What direction are we headed with the domain model?

…the answers were never clear to me. Often one technician on the team had the answer, but I didn’t feel empowered with the knowledge to act without their consultation.

DDD hits home the importance of Domain Models and presents infinitely more information than development guidelines like ‘objects should have both state and behavior related to that state’. My most significant learning from it is an approach for distilling real world concepts into software, concepts that linger in the mind of domain experts but never crossed the divide. I won’t go into detail here, but the book presents the essence of distilling those concepts - unifying the language used across roles and, more generally, throughout the team.

It’s now a rare day when a team member’s ear won’t be ringing to the sound of me stressing the importance of modeling objects on domain principles, rather than abstract, somewhat related or technical ones. Analysts directly contribute to assembling simplified object models and are on the receiving end of questions like ‘does this concept have a name?’, ‘is there a general concept that encapsulates these things?’, ‘can we break this thing down, what do you think it’s composed of?’, ‘how would you identify each of these?’.

From a requirements perspective, it’s shifted my focus from understanding the requirements and acceptance criteria in isolation to understanding the core domain; the business of the users. According to the Kano Quality Model, customers are delighted when they discover new and useful features, stuff they wouldn’t expect to see. Immersion in the domain is key to having this capability.

From a development perspective, it’s given me techniques to aid modeling the domain in software. They focus on keeping the software simple and reducing translation time between the software and the domain. Again, I won’t spell out in detail what’s best covered by the book, but it is the kind of stuff you can start practicing immediately, the majority of it transcends languages and is bound to be relevant for many years.

The book also offers solid advice to leaders on effective team structures and subdividing teams and domains. This ground is probably less explored than other parts of the book but it’s no less important. From my experience it is used less, quite simply, because changes of that magnitude requires organizational clout that is difficult for a team to ascertain.

Here’s a brief list of observations from my DDD experiences:

  • I find myself spending more time thinking, less time doing while at the same time being more productive
  • I’m more proactive in engaging analysts. Emotionally there’s less of a divide between developers and analysts
  • The code is more consistent and easier to navigate. You are less likely to be able identify the code of an individual
  • You fear changes to the code less
  • You strive to the understand the business’ problems more and focus less on simply producing software
  • Design discussions are welcomed and flow naturally, there’s often less friction
  • Breakthroughs, refactorings that significantly simply the implementation, come earlier rather than later

Credit where credit’s due; this book is quite simply an excellent geek read. For more info see Domain-Driven Design.

Agile Illusion

{Monday, February 27th, 2006}

Agility is not solely found in practices. Developers may implement stories, you may practice continuous integration, pair, practice TDD, DDD, <Any>DD - just because you do doesn’t make you Agile.

Actually I’m going to go out on a limb here with this: ‘Most organizations who believe they are Agile are actually far from it.’

The big thing that’s missing: Authority. Teams are often hamstrung by politics and power struggles preventing them from autonomous control over their practices and processes.

Another thing that’s often missing: Courage. The courage to try something for an iteration and learn from it. If a suggestion has merit why fear the consequences when engrained in your pschye is rapid feedback allowing you to try and try again? With rapid feedback teams should be thinking more of opportunity than consequence.

Can your team respond to change? Can you respond to the opportunity to improve by tweaking processes and practices? You may have the intellectual capability, but do you have the authority?

Putting lipstick on a pig doesn’t make it catwalk material.

Taking the authority to tweak processes for solving a problem away from the problem solvers is an excellent technique for building resistence and disenchantment. By doing this within a short period of time an organization will have guaranteed capability to hit the drink market with a new explosive product: ‘Bottled Frustration’.

The teams methodology will start conforming to that of the dictatorship imposed on them. Sure, the team can build Firewalls and Anti-Corruption Layers but the best they’ll do is practice ‘Agile in a Bubble’ - a virtual world detached from the reality of the organization.

In these environments the big challenge is to establish Trust with those imposing resistence. Building up a record of excellent delivery is great, but that’s little comfort when you’re the team trying to build that track record.

For mind in these cases your ability to justify your teams beliefs, practices and processes is invaluable. I’m surprised how few people appreciate the fundamentals of what they do and why they do it - if you lack the ability to defend what it is you do you are nothing short of a pawn in game played by others. So, knowledge and logic is one part of the justification effort - that’s your core arsenal. But how you deliver that is equally important - leadership and charisma play a massive part.

Knowledge can be learned. It would be nice if that were true of leadership and charisma.

For those lacking these traits, ‘Bottled Frustration’ and idealism can come to fore radiating fanaticism. At best in these cases the team will appear to be moving forward, but in reality the escalator that is the organization slowly moves them backwards.