Monday, February 15, 2010

BDD style tests for bidding

BDD stands for Behavior Driven Development, and it is one of those 2nd generation agile practices that I found difficult to buy into. BDD style tests follow the pattern: "given (some initial conditions), when (some action is taken), then (expect result)." This template seemed like such a no-brainer, that I could not see how it could warrant a separate name and whole movement formed around it. But then TDD itself (Test Driven Development) also is simple to define, and yet strict adherence to it forces revolutionary changes in a developer's mindset. Take a look at the following test written without BDD, which uses the latest evolution of bidding domain classes to demonstrate when to raise partner's major suit:

public void testRaisePartnersMajorDespiteStrongerMinor() {
  auction.bid(ONE_HEARTS);
  auction.bid(PASS);
  BiddingAgent ba = new BiddingAgent(auction, 
    new Hand("K,10,7,6","A,9,8,3", "A,8,6,4,2", ""));
  assertEquals(THREE_HEARTS, ba.getBid());
}

Now note how much easier it is to understand, when code follows the BDD template:

public void testRaisePartnersMajorDespiteStrongerMinor() {
  givenBidding(ONE_HEARTS, PASS);
  andPlayersCards("K,10,7,6", "A,9,8,3", "A,8,6,4,2", "");
  expectPlayerToBid(THREE_HEARTS);
}

The reason for this leap in expressiveness is that there's certain amount of useless ceremony around the domain objects, and that ceremony detracts from clarity of intent. By enforcing a strict BDD style on the tests, it's harder to be distracted by the ceremony. BDD puts focus on how the domain is modeled in human language, not in the code. The code model is decoupled from the spec by methods describing the context: givenBidding(), andPlayersCards(), and expectPlayerToBid(). One payoff of this approach is that hundreds of unit tests do not have to be modified when some aspects of the model are refactored. Another result is a set of test that can be shown to domain experts for verification. Both of these give boost to productivity.

1 comment:

  1. Interesting. I wasn't even aware I was invoking BDD, I was just trying to make my unit tests more readable. Thanks for the clarification. I am now devoted to BDD.

    ReplyDelete