Archive

Archive for the ‘BDD’ Category

Executable stories

June 19th, 2007

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?

BDD

Don’t test your privates!

May 18th, 2007

This blog post brought to you by the wonderful ambiguity of the English language!

And now back your regularly scheduled program ….

“How do I/Should I test private methods?”

This question seems to come up quite often. In this article I hope to convince that not only do you not need to test your private methods but that it is also bad practice.

Do what do I mean when I say “don’t test your private methods”? Am I telling you not to test code that might break? Not at all. What I mean is when you follow these two principles:

  1. Code from the outside-in
  2. Code to an interface, not an implementation

you will not need to go to any lengths to test your private methods. The first principle is why you won’t need to test private methods and the second is why it’s bad practice to test them. To better understand this lets look an example:

We’ll start with a test


procedure MyStack.ShouldPushItems;
begin
  FStack.Push('foo');
  CheckEquals(1, FStack.GetCount);
end;

And now lets fill in some code to make it compile:


type
  TMyStack = class(TObject)
  private
    FData : TStringList;
    procedure DoPush(const Value : string);
  public
    constructor Create;
    destructor Destroy; override;
    procedure Push(const Value : string);
    function GetCount : Integer;
  end;

implementation

procedure TMyStack.DoPush(const Value : string);
begin
  FData.Insert(0, Value);
end;

procedure TMyStack.Push(const Value : string);
begin
  DoPush(Value);
end;

function TMyStack.GetCount : Integer;
begin
  Result := FData.Count;
end;

No surprises here (except that I left out the constructor and destructor code). The test now passes with this code. Now how do we make sure that the value we pushed onto the stack was actually stored? That is to say, how do we know DoPush() did its job? How do we test DoPush()? We can’t look at the internal storage because it’s private and we don’t want to break encapsulation for testing. We don’t yet have a Pop() method as our test didn’t call for it.

So what do we do? Right now our testing context is very generalized and non-specific; just a stack. Let see what changing our testing context could get us:


procedure MyStackWithOneItem.SetUp;
begin
  FStack := TMyStack.Create;
  FStack.Push('foo');
end;

procedure MyStackWithOneItem.ShouldHaveACountOfOne;
begin
  CheckEquals(1, FStack.GetCount);
end;

procedure MyStackWithOneItem.ShouldPopThePushedItem;
begin
  CheckEquals('foo', FStack.Pop);
end;

And now some code to make it compile:


{ this is a private method }
function TMyStack.DoPop : string;
begin
  Result := FData[0];
  FData.Delete(0);
end;

function TMyStack.Pop : string;
begin
  Result := DoPop;
end;

So now our testing context is a stack with one item pushed onto it. We already know that ShouldHaveACountOfOne() will pass since we proved it in the previous iteration of the code. However, we still need to prove that the item we pushed onto the stack was indeed stored. That’s where ShouldPopThePushedItem() comes in. We’re able to infer that DoPush() did its job by verifying it using Pop().

But wait! What about DoPop()! We didn’t test that! You right … while we did check that the value returned from Pop() matched our pushed item there is one behavior of DoPop() that we didn’t check: the stack should now be empty. Let add a test:


procedure MyStackWithOneItem.ShouldBeEmptyAfterPop;
begin
  FStack.Pop;
  CheckEquals(0, FStack.GetCount);
end;

Remember that DUnit runs SetUp() before each test. ShouldBeEmptyAfterPop() will find the stack containing one item even though it executes after ShouldPopThePushedItem().

By changing our testing context we were able to verify that our private methods worked the way we expected them to.

Now, why is it bad practice to test private methods? Well lets say we made some decisions that led us to expose the internal data storage so that we could verify that Push() worked by accessing the internal storage. What happens when we refactor the code to use some other form of storage? This is where “Code to an interface, not an implementation” comes in. In our case Push(), Pop() and GetCount() make up the interface to the stacks implementation. Our test shouldn’t care about how the stack does its work any more than our customers care. As long as Push(), Pop() and GetCount() work the way they’re expected to work then all is well.

Given this arrangement let say that we decide to refactor the stack to store its data in database. I’ll leave the code for that as an exercise for the reader (!). Even though this is a large change to the code we can proceed with confidence. Why? Because our tests will tell us when we’ve broken something. Why can we rely on the tests? Because when we embarked on this big change the tests were passing and as we make this change, we don’t have to change the tests.

So, please, don’t test your privates. =)

BDD, XP

dSpec checked into SourceForge

April 30th, 2007

http://sourceforge.net/projects/dspec

You can get the very latest code from the SubVersion repository. While I haven’t released a new package of files yet you can get the latest and check out the new AgileDox stuff as well as some new specs for strings and integers.

BDD

AgileDox style output

April 26th, 2007

I really like having specs that read like plain English. Communicating behavior and intent between developers is very smooth this way. But why should we developers get to have all the fun? How about including your QA and analysts in the fun?

StringSpecification - Should have specs
–Specify.That(Boolean).Should.Equal(True)
StringSpecification - Should evaluate equality
–Specify.That(String).Should.Equal(Greetings Footpad!)
StringSpecification - Should evaluate inequality
–Specify.That(String).Should.Not.Equal()
StringSpecification - Should evaluate numeric
–Specify.That(String).Should.Not.Be.Numeric
StringSpecification - Should evaluate alpha
–Specify.That(String).Should.Be.Alpha
StringSpecification - Should evaluate alpha numeric
–Specify.That(String).Should.Be.AlphaNumeric
StringSpecification - Should evaluate beginning of strings
–Specify.That(String).Should.StartWith(Greetings)
StringSpecification - Should evaluate string contents
–Specify.That(String).Should.Contain(Foot)
StringSpecification - Should evaluate end of strings
–Specify.That(String).Should.EndWith(pad)
StringSpecification - Should have case insentive modifier
–Specify.That(String).Should.Equal(GREETINGS FOOTPAD!).IgnoringCase
StringSpecification - Should evaluate empty
–Specify.That(String).Should.Not.Be.Empty

(The actual output is formatted nicer than what I can reproduce in the WordPress editor)

I’ve been playing around with AgileDox style output from dSpec. If you’ve gone to all the trouble to represent your requirements as test cases why not have the test cases output documentation?

What do you think?

Update -

Ooooo - or how about this: an optional ContextDescription you can use to describe what you’re specifing

StringSpecification - Should evaluate empty
–When a string = ‘Greetings Footpad!’, Specify.That(String).Should.Not.Be.Empty

BDD

dSpec - BDD for Delphi

April 20th, 2007

dSpec.rar

Released under the Mozilla Public License 1.0 (MPL).

This release adds specifiers for Interfaces: Support() and ImplementedBy().

Specify.That(MyIntfList).Should.Support(IInterfaceList);

Specify.That(MyIntfList).Should.Be.ImplementedBy(TInterfaceList);

See the specs in the specification folder for the full list functionality.

Have fun!

BDD

dSpec update

March 5th, 2007

Grab the code here: dSpec.rar

What’s new?

First, some semantics. In the last iteration you said:

ShouldEqual()
ShouldNotEqual()

Now you say:

Should.Equal()
Should.Not_.Equal()

You can use “Not_” on any specifier. Additionally you can now say:

Should.Be.GreaterThan().And_.Be.LessThan()

You can string together specifiers using “And_”.

I’ve added some new specifiers:

GreaterThan()
LessThan()
AtLeast()
AtMost()
Nil_()
Assigned()
DecendFrom()
OfType()
True()
False()

Also, all specifiers can be modified where before only ShouldEqual() could be modified.Some examples of some wild specs:

TheNumber := 3;
Specify.That(TheNumber).Should.Equal(3).And_.Not_.Equal(2).And_.Not_.Equal(4); // 5 is right out!

Specify.That(False).Should.Not_.Be.True.And_.Be.False.And_.Not_.Be.True;
Specify.That(42).Should.Be.AtLeast(40).And_.Not_.Be.GreaterThan(50).And_.Be.LessThan(50);

Have fun!

BDD

dSpec alpha

February 23rd, 2007

Release early and release often … =)

I’ve uploaded my first go-around here: http://www.delphixtreme.com/downloads/dspec/dSpec.rar

dSpec is an extension of the DUnit framework. Behavior specifications are creating by descending from TContext (instead of TTestCase) and using published methods to execute the specifications (just like in DUnit). As discussed in the previous blog entry you assert behavior using the Specify.That method instead of using CheckEquals. Where before we would have said:

if WeAreInSectorZZ9PluralZAlpha then
CheckNotEquals(42, TheAnwserToLifeTheUniverseAndEveryThing)
else
CheckEquals(42, TheAnwserToLifeTheUniverseAndEverything)

We can now say:

Specify.That(TheAnwserToLifeTheUniverseAndEverything).ShouldEqual(42).Unless(WeAreInSectorZZ9PluralZAlpha);

(that line was a little too long for this blog theme. See the example project for the whole Hitchhikers Guide to the Galaxy joke =P )

As you can see we can modify the specification “ShouldEqual” with “Unless”. We can even say:

Specify.That(f).ShouldEqual(3.5).WithAToleranceOf(0.01).Unless(ToleranceIsInvalid)

Here we string together many modifiers.

See the dSpecBehaviors project in the specifications folder of the archive for more examples.

Remember this is a first stab. I only implemented enough to show how this sort of thing might work. I’m interested in hearing your comments.

BDD

BDD and Delphi

February 21st, 2007

For a primer on what BDD is, go here: http://dannorth.net/introducing-bdd/

So far there seems to be little code out there implementing the ideas of BDD. As Dave Astels and Dan North put it, we need a change in vocabulary to support our change in thinking. They tell us that xUnit frameworks use the vocabulary of “testing” and we need new frameworks to support the ideas of “specifying behavior”. There are two frameworks out there supporting these ideas: rSpec and nSpec. We will probably soon see jSpec. This brings me to the topic for this post: dSpec.

How to change the way we test?

Statements like this:

procedure TMathTestCase.Test2Plus2;
begin
CheckEquals(4, 2 + 2);
end;

are familiar to DUnit test writers. When you read it you need to know a few things for the test to make sense. It’s this translation of requirements to code that BDD is looking diminish, if not totally eliminate. BDD would suggest making this look like:

procedure TMathBehavoirs.ShouldAddUpToFour;
begin
Specify.That(2 + 2).ShouldEqual(4);
end;

When you read this statement it’s very clear what the expectation is. You don’t need any special knowledge to understand the assertation. You might even want to go a step further and say:

Specify.That(2 + 2).ShouldEqual(4).Unless(ImInAnotherUniverse);

Again, this reads very nicely.

Just so we all know that we’re talking about, let me introduce you to the components of the above statement:

Specify - The object to contain many overloaded versions of That
That - The function that takes the value as a parameter and returns an ISpecifier
ShouldEqual - a method of the ISpecifier that evaluates equality and returns an IModifier
Unless - a method of the IModifier that evaluates a condition

And this is where I am in building the dSpec framework. I have, however, encountered a problem …

Let’s say you want to specify the following:

f := 3.5001;

Specify.That(f).ShouldEqual(3.5).WithAToleranceOf(0.01);

This reads very nicely but it’s impossible to evaluate (at lease the way I have it now). Right now, the specification fails at ShouldEqual(3.5) because, of course, 3.5 does not equal 3.5001; we never make it to our call to WithAToleranceOf . We could put the modifier before the specifier like this:

Specify.That(f).WithAToleranceOf(0.01).ShouldEqual(3.5);

but that doesn’t read as nice. And neither does this:

Specify.That(2 + 2).Unless(ImInAnotherUniverse).ShouldEqual(4);

I don’t like the way Modifier-Specifier reads; I much prefer Specifier-Modifier.

I’m interested in hearing other peoples ideas on how to tackle this problem. If you’re interested in the code I have thus far you are welcome to it; just let me know.

Comments are open for this post.

Update

Solved the above problem. Assertations can be made in the Specifier-Modifier pattern. Please see the dSpec Alpha post for example code.

BDD