I have been attempting to write a big article on my experiences of BDD/ BDD style testing or what ever you want to call it. However, I have learnt that big über articles generally are never finished (by reader or writer) so I have cut it down a bit…

So I have been using a style of BDD for my current project for a couple of months now. As this was intended to be a ’smart UI’ application (no smirks at the back please…), I have only picked a few isolated areas that could be separated out and done properly. What I now have is a big mishmash of different styles, tests etc. but overall I am happy with the approach I have taken. As the part of the app I am dealing with has lots of rules, exceptions, caveats etc., expressing these in BDD-style sentences has had a big payoff. Only the other day I was asked how we handle a particular piece of data/conditions and all I had to do was read the names of my tests and I had the answer for them without having to remember anything ( I don’t remember code I have written 2 days ago, let alone 2 weeks ago!).

Anyway, there are some things I have got wrong. I haven’t really stuck to a Given->When->Then structure. I seem to have cobbled together the Given/When bits with a few ands. i.e.:

When the user requests money from his account and the pin is correct and he has enough money and he requests 10 pounds and he is wearing a brown that then return 10 pounds from the cash machine and debit his account by 10 quid

Whereas a better structure may be:

Given that the user is wearing a brown hat and he has enough money and he has entered the correct pin number, When he requests ten pounds then a £10 note should be returned from the cash machine and user’s account should be debited by ten pounds

It’s bit more wordy, but it scans better and more importantly can be converted into some sort of code:

    public class When_user_requests_ten_pounds : 
                              User_wearing_brown_hat_and_has_enough_money_and_entered_correct_pin
    {
         public void Debit_his_account_with_10_pounds()
         {
         }
 
         public void Return_10_pounds_from_the_cash_machine()
         {
         }
    }

Anyway this is all well and good until I start getting into counter examples. For example, if I had the following scenario and expected behaviour:

Given that the moon is in the seventh house and jupiter aligns with mars, when a new age dawns then this should be the dawning of the age of aquarius.

(the original sort of scans better)

I could fulfill the conditions of this slightly bizarre requirement with the following (equally bizarre) code:

       public class NewAgeDawner
       {
             public NewAge DawnNewAge()
             {
                  return NewAge() {OwnedBy=Zodiac.Aquarius};
             }
       }

That would essentially cause the tests to pass but is obviously wrong as it happens whether the scenario is set up as described or not (i.e. it always dawns the age of aquarius regardless of position of moon and jupiter/mars alignment). At this point I find it useful to go back to my early electronics lessons and write a bit of a truth table to describe the behaviour I need to see:

Moon in 7th Jupiter aligned with mars Age of aquarius?
0 0 0
0 1 0
1 0 0
1 1 1

So even though I only care about the last item in this list (where both conditions are met) I have to write 4 tests. Not that I am complaining at all (not me…) – the more test code the better, but given that three of the four outcomes should have the same result, it’s a lot of duplication. For example, I have some behaviour in my system that sets a couple of fields based on arguments passed in and then persists the object to the database. However, there are a number of states in which the operation cannot succeed and I want to make sure the fields are not changed, and the operation returns a suitable result message explaining why it couldn’t work. For each of these invalid states, I must write three tests:

		[Test]
		public void Result_is_failure()
		{
			Result.Success.ShouldBeFalse();
		}
		[Test]
		public void Error_message_explains_failure_reason()
		{
			Result.Message.ShouldEqual("Moon is not in the seventh house...");
		}
		[Test]
		public void Save_not_called()
		{
			MyRepository.SaveWasNotCalled();
		}

With the exception of the message (which will change each time), I have to copy paste all these tests for each invalid state. Is this really the right thing to do?

I know we should be free and easy with our test code and write as much as is necessary – generally ending up with more test code than production code, but by copy pasting?? Is there a better way?