Executable stories
For some time the (for lack of a better word) founder of BDD, Dan North, has been working on a BDD framework from Java called jBehave. The idea behind jBehave is to make stories and their associated scenarios executable. I’ve sent some time looking at jBehave and decided it looked a little too cumbersome for my taste. This week Dan released rBehave for the Ruby language. For some reason I’ve been able to sink my teeth into this more than jBehave. As such, I’ve started a Delphi implementation. Using Dans example story and scenarios:
Story: transfer to cash account
As a savings account holder
I want to transfer money from my savings account
So that I can get cash easily from an ATM
Scenario: savings account is in credit
Given my savings account balance is $100
And my cash account balance is $10
When I transfer $20
Then my savings account balance should be $80
And my cash account balance should be $30
Scenario: savings account is overdrawn
Given my savings account balance is -$20
And my cash account balance is $10
When I transfer $20
Then my savings account balance should be -$20
And my cash account balance should be $10
(For more on BDD stories see Dan North’s article What’s in a Story)
I’ve come up with some code that looks like this:
procedure TransferToCashAccount.SavingsAccountIsInCredit;
begin
Given('my savings account balance is', 100, SavingsAccountBalanceKey);
Given('my cash account balance is', 10, CashAccountBalanceKey);
When('I transfer', 20, DoTransfer);
&Then('my savings account balance should be', 80, SavingsAccountBalanceKey);
&Then('my cash account balance should be', 30, CashAccountBalanceKey);
end;
procedure TransferToCashAccount.SavingsAccountIsOverdrawn;
begin
Given('my savings account balance is', -20, SavingsAccountBalanceKey);
Given('my cash account balance is', 10, CashAccountBalanceKey);
When('I transfer', 20, DoTransfer);
&Then('my savings account balance should be', -20, SavingsAccountBalanceKey);
&Then('my cash account balance should be', 10, CashAccountBalanceKey);
end;
The elements in play are:
- Given - sets a value in the world (context)
- When - executes an action
- Then - verifies that a value in the world (context) is that which is specified
There is one other element that’s not immediately visible here: the World. The world is simple a holding area for values. In this case we store the values of the savings account balance and the cash account balance in the world for manipulation in the When action. The DoTransfer method looks like this:
procedure TransferToCashAccount.DoTransfer(Value: Variant);
var
TransferAmount,
SavingsAccountBalance,
CashAccountBalance : Currency;
AccountTransferObject : IAccountTransfer;
begin
TransferAmount := Value;
SavingsAccountBalance := World[SavingsAccountBalanceKey].Value;
CashAccountBalance := World[CashAccountBalanceKey].Value;
AccountTransferObject := TAccountTransferObject.Create;
AccountTransferObject.TransferAmount(SavingsAccountBalance, TransferAmount, CashAccountBalance);
World[SavingsAccountBalanceKey].Value := SavingsAccountBalance;
World[CashAccountBalanceKey].Value := CashAccountBalance;
end;
I built this on top of DUnit both for speed and the ability to mix these executable stories in with the unit tests or BDD specs used to implement the code. You can check out what I’ve done so far here:
dBehave.rar
What do you think?
Trying to revive Prolog?
Just curious, and don’t read this as bashing on the idea, but is this something done as a proof-of-concept or trying to find a better way to do something “in the real world”?
On the “good” side, I never knew one could create a method using a reserved keyword by prefixing it with an ampersand, so that’s something new I learned today!
Very nice!
I was reading Dan North’s article yesterday and thinking about it …
What I find difficult to believe is the customer actually taking a look, understanding and commenting the stories. There is too much use of paper for specs
Also, I wonder how would a bug in such a story would be presented, especially for regression tests … Maybe this is not the expected use for xBehave though
An amazing machine, you deserve to 1. These fantastic shoes can be a brilliant and attractive. Enjoy and of itself.
It help me very much to solve some problems. Its opportunity are so fantastic and working style so speedy.