Showing posts with label BDD. Show all posts
Showing posts with label BDD. Show all posts

Wednesday, November 19, 2008

BDD - Available Frameworks

I've been using the Astels style of BDD for a while now but so far I've just done it using MSTest/NUnit and a few custom base classes. I think that's a good way to start out, as with so many good things in life it doesn't require a new whizzy tool/framework.

However I've just joined a new project and we've been looking at different frameworks that are available for unit testing and for BDD so I thought I'd post about what I've seen so far. Any opinions would be gladly received.

MSpec
This project is very cool, not only does it allow you to create superb specifications but you also get some nice reporting. Here's a simple example of a sample spec:

public class When_adding_a_contact_to_a_user_with_no_existing_contacts
{
private static User _user;
private static Contact _contact;

Establish context_once =()=>
{
_user = new TestUserBuilder().Build();
_contact = new ContactBuilder().Build();
};

Because a_context_is_added =()=>
_user.Contacts.Add(_contact);

private It should_associate_the_contact_with_the_user = () =>
_user.Contacts.Contains(_contact).ShouldBeTrue();

}

One thing to note is if your planning to look at MSpec then you'll probably want to download the Machine codebase since there aren't many examples of using MSpec on the Web the examples with Machine are a good starting point.

So far there's no R# integration but that doesn't worry me at all as if needed it will come and this is still a very early version.

The reporting seems to work well, but we primarily use this style for unit/integration tests and so we are unlikely to present the reports outside the development team. Having said that Aaron pointed out that they can be useful within the development team, which makes a lot of sense.

Overall my main worry is the syntax could be a bit much for some people, in particular if you go for the compact style:

NUnit
I think there's a good argument for just using a base class, especially when you are getting going with the approach:

public class When_adding_a_contact_to_a_user_with_no_existing_contacts : SpecificationBaseNUnit
{
private User _user;
private Contact _contact;

protected override void EstablishContext()
{
_user = new TestUserBuilder().Build();
_contact = new ContactBuilder().Build();
}

protected override void Act()
{
_user.Contacts.Add(_contact);
}

[Test]
public void should_associate_the_contact_with_the_user()
{
_user.Contacts.Contains(_contact).ShouldBeTrue();
}
}
This is a hopelessly naive example but you get the idea. You lose some of the syntax niceness, suddenly the specs themselves take up multiple lines because of all the curlies. You've also lost reporting, unless you put in some work yourself. However it is a little easier to understand and when introducing TDD/BDD that could be important.

XUnit.net
I'm no XUnit.net expert but Ben Hall convinced us to give it a shot by recommending it and it is very nice. You can read about an approach that works here. If you use the specification base class described in that post you might end up with this:

// Using base class influenced by http://www.bjoernrochel.de/2008/10/04/introducing-xunitbddextensions/
public class When_adding_a_contact_to_a_user_with_no_existing_contacts : SpecificationBase
{
private User _user;
private Contact _contact;

protected override void EstablishContext()
{
_user = new TestUserBuilder().Build();
_contact = new ContactBuilder().Build();
}

protected override void Because()
{
_user.Contacts.Add(_contact);
}

[Observation]
public void should_associate_the_contact_with_the_user()
{
_user.Contacts.Contains(_contact).ShouldBeTrue();
}
}
One aspect of XUnit that might throw you is how opinionated it is, which could be an advantage or a disadvantage. An example is that it's aiming for each test to run in isolation, so the fixture class is re-created each time and if you really want to reuse the fixture you implement IUseFixture. I guess this is a very safe approach because it means tests/specs are extremely unlikely to affect each other, but it actually seems over-kill if you're using a style where the specification methods only assert (no side-effects).

The lack of messages on assertions seems sensible, and it is for small focused BDD specifications, but if you use it for integration testing you would want the option of adding a message in.

On the syntax front we could always go for more flexibility:
public class When_a_user_has_no_contacts : FlexibileGrammarSpecificationBase
{
private User _user;
private Contact _contact;

protected override void EstablishContext()
{
_user = new TestUserBuilder().Build();
_contact = new ContactBuilder().Build();
}

[Because]
protected void and_we_give_them_a_new_contact()
{
_user.Contacts.Add(_contact);
}

[Observation]
public void the_contact_should_be_associated_with_the_user()
{
_user.Contacts.Contains(_contact).ShouldBeTrue();
}
}
However this seems a little pointless to me so I've dumped the idea.

Summary

We decided to go with XUnit.net but we also plan to look at Ruby based solutions including RSpec and Cucumber. Cucumber seems exciting as it lets you specify table based specifications, theoretically allowing us to get the advantages of a FIT style approach without having to use FIT (or SLIM) itself.

Ultimately there is a lot going on in the BDD space in Ruby-land (and a book on the way) and the language does suit it quite well so we intend to do some playing.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

BDD and Parameterized testing

Although I really like Astels style BDD (to me a constrained/enhanced style of TDD) I still use a lot of parameterized testing and though I should give you an example why, using XUnit.net.

Lets say we're testing simple SPECIFICATION style rules, we might write:

[Concerning(typeof(ValidEmailRule<TestEntity>))]
public class When_using_rule_on_a_null_string : SpecificationBase
{
protected TestEntity _testEntity;
private bool _isSatisfied;

protected override void EstablishContext()
{
_testEntity = ContextSetup.CreateTestEntityWithValue(null);
}

protected override void Act()
{
_isSatisfied = new ValidEmailRule<TestEntity>(_testEntity, x => x.Value).IsSatisfied();
}

[Observation]
public void is_satisfied()
{
_isSatisfied.ShouldBeTrue();
}
}

This just tests how the rule handles a null value, but we'd then want to test with all sorts of other values (valid and invalid). To compare lets thus look at how easy it is to test a variety of invalid e-mail address using one of XUnit.net's parameterized testing approaches (see Ben Hall for more options):

[Concerning(typeof(ValidEmailRule<TestEntity>))]
public class When_evaluating_invalid_email_addresses
{
[Theory]
[InlineData("sddas.com")]
[InlineData("sddas@")]
[InlineData("@")]
[InlineData("@blah.com")]
[InlineData("sddas@@blah.com")]
[InlineData("1213231")]
public void is_not_satisfied(string invalidEmailAddress)
{
var testEntity = ContextSetup.CreateTestEntityWithValue(invalidEmailAddress);

var isSatisfied = new ValidEmailRule<TestEntity>(testEntity, x => x.Value).IsSatisfied();

isSatisfied.ShouldBeFalse();
}
}

Now you may disagree with my approach here, this isn't as readable as it could be, but I think you can see why you'd use this approach if you have a lot of values to validate.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Tuesday, October 28, 2008

BDD - Files/Folders/Namespaces (BDD)

Files/Folders
One thing that can be troublesome when moving from TDD to BDD is how to organize your files and folders, so far I've tried two approaches:

  1. One class in each file - So if you have When_associating_an_order_with_a_customer and When_associating_an_order_with_a_preferred_customer then they'd be in seperate files even though they are very closely related. If they share a base class, or a class they both compose, then that would be in yet another class (presumably).
  2. Multiple classes per file - As an example you might group the Order addition contexts into a file called OrderPlacementSpecifications, the file could also contain the shared base class (if you went down that road).
To me the second approach has a couple of advantages:
  1. Gives the reader extra information - By grouping the two order placement classes we tell the reader that they are quite closely related.
  2. Simplifies folder structure - If we go for the other approach, one class in each file, then we're probably going to have to have more folders. The addition of the extra files and folders definitely makes the solution file harder to structure.
To give you an idea here's a screen shot of a part of the folder structure for a sample app we're doing:

Namespaces
In addition to files/folders I've tried a few approaches to structuring namespaces but the approach I'm trying now groups related artifacts. For example:
  1. Specifications.Users.Domain
  2. Specifications.Users.Domain.Contacts
  3. Specifications.Users.Services
  4. Specifications.Users.Domain.Repositories
  5. Specifications.Users.UI.Controllers
The "Specifications" bit adds very little but I think grouping all specifications related to users is useful, not least as R# makes it easy to run all the specifications in a namespace. This can be useful if you have a big solution and only want to run the specifications for the area your working on. Its also worth saying that its "Users" to avoid clashing with the "User" class.

Folder wise however we're using a standard approach where your Repositories are in a completely seperate folder from your controllers, even though they might both relate to a particular entity. To me the lack of relationship between our folders and namespaces isn't a problem though, with R# its easy to find a file/type and in addition the folder/namespace tell you two different things about your codebase (one by "layer", one by "feature").

So I'm interested in peoples views? I'm guessing you'll all dislike it though because from what I've seen no matter what you do people will be unhappy with your file/folder/namespace scheme. Pluse we'll probably turn against this approach next week....

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Wednesday, August 06, 2008

Acceptance Testing Book on CodePlex

Geoff Stockham was good enough to send me a link to a CTP of a new acceptance testing guide written by a group of authors that include Gerard Meszaros.

Really looking forward to reading the final version it as I am hoping that it will answer some of my questions about how to tackle acceptance testing, especially within the context of BDD.

My initial scan left me thinking that it's quite high level, for example the "Hand Scripted Test Automation" section doesn't really tell you much about how to write good acceptance tests in the context of Acceptance Test-Driven Development. However it is early days and it looks like a lot more is to come so I'm sure it will be useful.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Sunday, August 03, 2008

BDD for Acceptance Testing (xBehave/Dan North)

As I said in my previous post on BDD I use the Dan North (xBehave) style solely for acceptance testing as I think it suits testing at that level.

The first problem with discussion this style is that the message isn't really all that clear, if you want evidence of this do a Google search for BDD and spend an evening reading as much as you can then see if you feel you understand what its all about. Given the fact that Dan North apparently first started working on BDD in late 2003 I'm surprised at the lack of good content. Having said all that I have few real answers in regards to BDD so I'm going try to explain some of the real issues I've met.

However many of these issues are not specific to BDD as they relate as much to the correct application of user stories and acceptance testing. However I thought it was worth discussing it all together because you will meet issues if you do try to follow Dan's style and some of them may surprise you even if you have read about BDD, especially since most BDD examples boil down to dull AccountTransferService type cases.

It is also worth remembering though that these are just my current opinions, and I have already changed my mind a few times on some of this stuff :)

What Are We Talking About Here

My acceptance tests are the highest level tests that I'm going to write as part of my normal development process. They aren't necessarily end to end but they will test to the boundary of one particular system, let me give you two examples of what I mean:

  1. Integration Project - The acceptance tests sent a message to the SUT and verified the XML document that came out the other end. I didn't go as far as testing how that XML document was processed by subsequent systems, writing these totally end-to-end tests might have had value but they would have been complex/slow/tricky and in my view would not have adequately driven development.
  2. Web Project - For the last month I've been working on a new Website and in this case we're using Watin/NUnit and the BDD specifications are working from the top down. They only interact with the application through the browser, including when verifying.

Just to be clear we are just talking here about the top level tests, so in the case of the Web any controller/mapper/service/entity tests are covered separately using the xSpec style (Scott Bellware is the authority on this in the .NET world).

Framework

As far as I'm aware the only serious .NET BDD framework is NBehave and whilst my (limited) work with it left me feeling that its a good approach I wasn't happy with the resulting specifications. Looking back now I think I made a mistake giving up on it too quickly and I do intend to try it again once v0.4 comes out.

Another BDD framework that you might have heard of is Stormwind. It looks very professional but it is very GUI focused and doesn't really seem to have that much to do with BDD. As soon as you start talking about the nitty gritty details of the user interacting with the controls on a page I think you've lost the power that BDD gives you about describing what your user wants to be able to do and why.

So in actual fact I'm not currently using any special framework for my acceptance tests other than (for the Web) Watin and NUnit/MSTest.

Style

Before starting out with BDD you need to know what your trying to get out of it. Personally I wanted to get:

  1. Good acceptance tests
  2. Improved communication within the team.
  3. Further cementing of the user story based requirements process.

You will notice reporting is not mentioned here because the ultimate goal is to create working software that meets users needs so personally I'm not overly interested in the reporting angle. With this in mind, and given that we have adapted our requirements process to ensure we produce stories in a suitable given/when/then format, how do we feed them into our development?  After a bit of experimentation my current approach is just to do it blindly by encoding them directly into methods:

Given_that_I_am_not_logged_in();

And_I_am_on_the_search_page();

When_I_login_successfully();

Then...

And_I_will_be_on_the_search_page();

Few things to note about this style:

  1. Managing Complexity - In this post about RBehave Dan North indicates that each steps implementation should be simple. I'm not so sure this is always true, for example when I was writing tests for the integration project there was a lot to be done to setup the test and to verify the results and with this style I hide all those details within the methods.
  2. Lacks Reporting - With this approach you don't get any reporting because we're just calling methods rather than passing useful metadata to a framework like NBehave, this means we can't print out a report to show our users. This doesn't bother me because the "user stories" are driving the creation of these specifications so I don't particularly see the value of printing out the results of an execution to say "look we're doing what we said". If we want to prove we've done the right thing we can look at the way the software behaves.
  3. Lacks Flexibility - I've met quite a few situations where I want to parameterise my given/when/then, for example even for this simple acceptance tests I have variations depending on where you are on the site when you login and one case where you go directly to the login page from outside of the site. I agree that DRY does not necessarily apply as much to tests as to normal code (which I will discuss in a separate post) but if I blindly copy the code in each case I end up with a real muddle.

What I've found is with acceptance tests there is a lot of complexity and scope for reuse and you can of course get the reuse in a number of ways including using inheritance or composition:

  1. Inheritance - You have a context base class and inherit into multiple subclasses. Most of the code is probably going into the base classes and the subclasses just override a few values/methods to customize the behaviour (e.g. overriding StartPage and EndPage or equivalent for the login case). It works but it does mean that the individual scenario classes tell you very little and to understand what's going on you need to go into the base class. Although the base class itself might be short and written in a very clean manner the result is far from perfect. Note even if you do use inheritance you will probably use some helper/builder classes, but this is beside the point.
  2. Composition - Do what xBehave does and move the context out to a separate class which you configure before running every scenario, so your given/when/then is moved to the composed class and you tell it what values to use in a particular execution.

Since the reuse is a big issue I might well blog about it separately, but I do think the amount of repetitive code involved in acceptance testing does push you towards a composition based approach and I do intent to give NBehave another shot sometime soon.

Outside In

As I discuss above I'm using this approach from the top down, but my usage has varied massively:

  1. Integration Project - I tried an outside in approach focusing on mocking first then replacing with real implementations. This approach was emphasized heavily in a lot of BDD articles and I found it relatively useful in helping me use mocking to influence my design.
  2. Web Project - In this case we're using Watin, no mocking is performed at any stage in these tests but we will stub out some services (e.g. Web services). My workflow is to start with a single Watin test and then once its failing I'll switch directly to testing the controller (using xSpec style), then services/repositories and so on right the way down until I've written enough code to get the original test passing.

The difference is small, but I certainly think its worth pointing out that BDD does not force you to work in one particular way.

Thoroughness

How many of these specifications do I write, well for me it depends and since I've now tried to use BDD on two projects I thought I'd describe how many acceptance tests I've written on each of them:

  1. Integration Project - In this case the SUT receives messages describing changes to an AGGREGATE and it then generates XML messages which are sent to BizTalk. My approach to acceptance testing was to modify the AGGREGATE, get the resulting message, feed it through the SUT and then verify the resulting XML matched my expectations. In this case we had (boring) complexity in the mapping, if Foo has the value X then do Y, and whilst I could have have tried to write acceptance tests for each of these cases but I was already covering that behaviour in my lower level tests and it was far more convenient to test/specify at that level. With this in mind I only wrote two acceptance tests, one with a relatively unpopulated aggregate and one that was fully populated with interesting values.  All the other details were covered by xSpec style unit/integration tests.
  2. GUI Project - Our user proxy writes user stories and scenarios that go into quite a lot of detail, these were then turned pretty much directly into acceptance tests. The result is lots of acceptance tests and they do indeed (so far) drive the development.

The integration project was troublesome, applying user stories and BDD involved a bit more creativity than in the case of the GUI work and the specifications didn't cleanly tie back to the requirements. Having said that the user stories themselves didn't go into massive amounts of detail about all of the little details so I thought I'd found a reasonable balance and the acceptance tests did have a lot of value and saved me time overall because I had less issues being discovered when we did end-to-end testing.

Outstanding Questions

Acceptance testing is hard and from what I've seen there just isn't the guidance out there and I'm quickly running into exactly the issues that make test automation (which used to be my job) very difficult. The main questions I still have are:

  1. Verifications/Setup - Assuming there is a GUI do I ever skip it when doing my setup/verify?
  2. Size - Do I go for one big happy path test or more detailed and targeted tests (which in my view are more useful)?  What about when in order to verify something I need to go to another part of the system?
  3. Maintainability - These tests use so much of the system that we have to make them maintainable, this isn't just about not encoding too many GUI details into the specifications but is also about allowing reuse and writing clean code. What's the best approach?
  4. Story Driven - In order to create user stories that feed into BDD nicely you need to write them a certain way, is this something the users should have to think about?

Note that these question relate to the process that a developer goes through in practicing BDD and the artifacts we produce, I have plenty of other questions about the overall process of BDD and how far it really changes software development.

Starting with BDD

If you are new to BDD I'd recommend you read Dan North discuss BDD and give it a shot. Once you understand the ideas maybe look at the BDD group and all the great content out there on the Web. However when reading content I'd make sure to continually ask whether the author is talking about the Dan North (xBehave) style or the Dave Astels (xSpec) style. If its the former then it is most likely that the author will be thinking of acceptance testing and the advice is probably worth considering, if its the latter then its quite possible they are thinking of unit testing which (to me) is a whole different ball game (in practical terms).

Also everything I've said above is questionable and subject to change, I'm also not strictly following what Dan North thinks. For example here's a quote from Dan North:

I use the scenarios to identify the “outermost” domain objects and services – the ones that interact with the real world. Then I use rspec and mocha to implement those, which drives out dependent objects (secondary domain objects, repositories, services, etc).

This makes sense but I've found using xSpec style works better for domain objects/services, so I actually use xSpec for everything below the GUI, but that might change again next month or if I work on a project with different characteristics.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Thursday, July 24, 2008

BDD - The Two Approaches

I've been using BDD for a little while now and think I've gotten to grips with most of the ideas, however the more I learn the more questions I have. Rather than wait for answers I thought I'd blog about what I'm trying now, so when reading this keep in mind that these are just my current personal opinions and should be taken with a pinch of salt.

My intention was to write one big blog entry but it immediately got too long and unfocussed so I decided to break things out a bit and I thought I'd start by describing how I view BDD.

To me there are two styles of BDD:

  1. North BDD (xBehave) - The style Dan North and colleagues created and evolved and which is often seen as the given/when/then style. To me this style will be useful in bringing everyone into the requirements process and getting them talking the same language whilst providing a process to ensure that the requirements feed directly into development. In my view best suited to higher level testing and in particular to acceptance testing.
  2. Astels BDD (xSpec) - The style Dave Astels popularised and which, to me, is a new form of TDD which has some serious benefits. You can use this style for any testing, from acceptance testing downwards.

Some have argued that the given/when/then style is not needed, and that the xSpec style can be used for all levels of testing. I've tried this but didn't entirely like the results so I currently use both approaches because I actually think that using a different testing styles for acceptance testing and all other developer testing has benefits, particularly because the two types of test/specifications are quite different:

  1. Level - Although many of the BDD examples are against the domain/service layer level I actually think that in many systems you'll actually be using this style for your acceptance testing, probably from the top down.
  2. Language - Dan North makes a big deal of the fact that BDD can draw in the UL. I'm not so sure this is true because user stories aren't necessarily in the UL. However even if it is true it only applies to some of the specifications we're writing, namely those describe the user experience (acceptance level) and domain model.
  3. Reuse - When you're writing acceptance tests you've got a lot of potential for reuse so, in my view, composition wins out over inheritance. I'll describe this more in a separate post, to me, that's the biggest technical reason to look at xBehave (I just found out this is also Dan's view, see comments on this post).
  4. Tools - I'll cover this later but although I think you can do both styles of BDD without any tools I do think that Dan North's style is the one that will benefit more from additional tools/frameworks (such as NBehave) particularly if you are interested in people outside the development team writing the inputs and seeing the outputs (notably reports).
  5. Patterns - In my limited experience patterns/approaches that you come up with for developer testing don't necessarily scale up to acceptance testing where there is more reuse/complexity. I thus think that when viewing much of what is written about BDD you need to be clear on what type of testing the person is describing.
  6. Intent - Users/domain experts are only going to be interested in the behaviour of some parts of the system, notably the GUI and the domain so using the xBehave style right the way down is an un-necessary burden.

Its unfortunate that Astels and North both called their approach BDD, but thats the way of it. However we do need to get our terminology straight and that starts with understanding the differences between the two styles of BDD.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Sunday, July 20, 2008

BDD Talk by Scott Bellware

Greg Young has posted a link to a talk given about BDD by Scott Bellware which I highly recommend. I like it most because Scott clearly explains the differences between the two styles of BDD, one influenced by Dan North (*Behave) and one by Dave Astels (*Spec). I also like the fact that slowly but surely we're starting to use different terminology for the two types because mixing them up is (I believe) the cause of a lot of the misunderstandings regarding what BDD is all about.

My feeling, as I've posted before, is that both approaches have a lot of value but unfortunately the given/when/then style seems to me to be work best with some tool support (especially so you can parameterise the given/when/then itself) so it is harder to get into. I'm going to post more about my views on this later though.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Sunday, April 27, 2008

BDD Discussion

BDD Divergence

The BDD Acceptance Testing thread over at the BDD forum is showing up what I consider to be the big problem in BDD at the minute, mixed messages.

On one side you have an approach that uses a context and specification approach to apply BDD style tests to all levels of specification, this is the approach where you might have a class called When_my_account_is_declined containing a specification called A_notification_is_sent_to_interested_parties. In my view this style is useful, I've been using it for unit testing and I like it a lot. Having said that I'm not intending to take a dump of the context/specification names for use by non-programmers in the team (e.g. domain experts) because a lot of the specifications will be too low level or technology focused. So far I'm primarily using this style to get nice readable specifications for use by the developers, so as a different style of TDD.

On the other side is the story/scenario driven approach that Dan North is pushing for, he also describes why he likes to separate these tests from classical programmer tests and the part they play in your process.

I personally think that you can use the two approaches together if you want to, using the given/when/then approach for acceptance tests and context/specification (or just normal TDD) for all other tests (including unit tests). You can of course use the context/specification style for the acceptance tests and dump given/when/then. Whether this is a good idea depends on whether the benefits Dan's approach brings (such as improving communication with non-programmers in the team) justify the effort of using the given/when/then style and to be honest I haven't used his style enough yet to have a strong view on it.

Are we automating Stories or Scenarios

Two interesting points that Dan makes in the acceptance testing thread are:

"As you quite rightly said, you can express any scenario in just a regular
example, or xunit test case."

..and..

"The scenario runner (not story runner - you don't run stories)"

He is clarifying that we run scenarios not stories. What is a scenario in this context, Scott gives a good definition in the BDD terminology thread:

"A scenario is a way to express acceptance criteria using an example-
driven approach.  A scenario can express more than one criteria if
needed.
"

The fact that you automate scenarios rather than acceptance tests is a good point to make.

Terminology

In the discussions on BDD we all seem to use consistent terminology, however the BDD terminology thread at the BDD forum is a good starting point to getting some consistency (which can only improve the discussion).

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Tuesday, March 25, 2008

Trying For Readable Tests

Whilst playing with using BDD style specifications to drive the granular design of my classes I've tried to see if I can also look at ensuring my tests are as readable as possible and I thought I should document my current thoughts on the results.

In this description I'll use the word specification/test interchangeably...I'm just not ready to talk about state or interaction specifications.

State Tests

I've been following the approach of having small test fixtures (contexts), for example:

using Concerning = System.ComponentModel.CategoryAttribute;
using Specification = NUnit.Framework.TestAttribute;
using Context = NUnit.Framework.TestFixtureAttribute;
using NUnit.Framework;

namespace AddressMapperSpecifications
{
[Context]
[Concerning("AddressMapper")]
public class When_mapping_addresses
{
#region Fields

private AddressDetails _mappingFrom;
private Address _mappingTo;

#endregion

# region
Context

[SetUp]
public void SetupContext()
{
_mappingFrom = AddressObjectMother.CreateAddress();

_mappingTo = new AddressMapper().Map(_mappingFrom);
}

# endregion

#region
Specifications

[Specification]
public void Street_one_is_mapped()
{
Assert.AreEqual(_mappingFrom.StreetOne, _mappingTo.StreetOne);
}

[Specification]
public void Street_two_is_mapped()
{
Assert.AreEqual(_mappingFrom.StreetTwo, _mappingTo.StreetTwo);
}

I like this style because it leads me to have small fixture/context classes, likely only a very few specifications are going to want to share exactly the same fixture so I avoid the issue of my classes getting too big.

I also think that the small fixture size and the class/test names together result in an approach that I find very readable.

Interaction Tests

As I see it you use use mocking for a few reasons, one of the most obvious ones is to for convenience. Say A calls B which calls C, if I write my tests for C but my clients use A then I need to show that when I call A we can expect C in turn to be called (and also can show the arguments/return values). I see this as mocking to make granular testing easier, there are other reasons to use mocking/stubbing but this discussion doesn't necessarily relate to them so well.

The previous example showed a state test/specification where just having an assertion (or assertions) in the specification method worked. Arguably moving the setup and interaction with the system under test (SUT) into the SetupContext method helped make it all more readable. We can't really do that so easily with mocking tests because in a mocking test you have to setup your expectations up front so the tests take take (basically) this form:

  1. Setup including setting expectations on the mock.
  2. Exercise the SUT.
  3. Verify that the expectations on the mock were met and optionally do other verifications.
  4. Cleanup (if required).

If we move the setting up of the mocks into the SetupContext method then we'd end up with a situation where each class had one specification (because its unlikely we'll want to setup the same expectations multiple times). Even worse looking at the specification method would tell you nothing because to understand a mocking test you need to start by looking in detail at the expectations.

I've thus found that so far my interaction tests are taking this form:

namespace AccountMessageMapperSpecifications
{
[Context]
[Concerning("AccountMessageMapper")]
public class Interactions_when_mapping_an_account : RhinoMockBase
{
# region Fields

private Account _subjectOfMessage;
private DomainMessage _messageToBeMapped;

private AccountMessageMapper _underTest;

# endregion

#region
Context

[SetUp]
public void SetupContext()
{
_subjectOfMessage = AccountObjectMother.CreateAccount();
_messageToBeMapped = new TestDomainMessageBuilder().WithDomainEntity(_subjectOfMessage).Build();

_underTest = new AccountMessageMapper();
}

#endregion

#region
Specifications

[Specification]
public void Primary_address_is_mapped()
{
IMapper<IAddress, Address> _mapper = Mocks.CreateMock<IMapper<IAddress, Address>>();

using (Record)
{
Expect.Call(_mapper.Map(_subjectOfMessage.Owner.PrimaryAddress)).Return(new Address());
}

using (Playback)
{
_underTest.Map(_messageToBeMapped);
}

_mocks.VerifyAll();
}

#endregion
}
}

DISCLAIMER: I've just bodged this together so it isn't great. I'm particularly not liking the way it looks when I pass a generic interface in to get a mock for it!

Most of the code is in the actual specification method, including all of the setup, the interaction with the SUT and finally the call to verify that the expectations were met. I've moved as much as I think I sensibly can into the SetupContext method but the fixture is still quite lightweight and reusable, for example I could easily put another method in that showed the interaction with another mapper (e.g. Telephone_number_is_mapped).

Overall though I think this style of interaction test is quite readable, and to me the combination of the two tests explains very well the behaviour of a low-level component (AddressMapper) and also the interaction that a higher level component (AccountMessageMapper) has with it.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Friday, March 14, 2008

BDD - Mock then replace

Just re-reading Dan North's article Introducing BDD and realized that I'd forgotten about this section:

At first, the fragments are implemented using mocks to set an account to be in credit or a card to be valid. These form the starting points for implementing behaviour. As you implement the application, the givens and outcomes are changed to use the actual classes you have implemented, so that by the time the scenario is completed, they have become proper end-to-end functional tests.

I must admit I haven't tried this approach yet but it is one that makes sense to me so I think I'll try it because I really think having end-to-end functional tests is very attractive.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

BDD - Uncle Bob's Stable State

In a TDD thread on tests as specifications there was a link to Uncle Bob talking about Stable State: An Emergent Rule, an excerpt is:

If you look carefully at the specification of the Bowling Game you will see that the state of the Game is changed only by the setup block within the context blocks. The specify blocks simply interrogate and verify state. This is in stark contrast to the JUnit tests in which the test methods both change and verify the state of the Game.

Really its the same idea as some people practicing BDD have, keep the test/specification methods small and preferably just doing Assertions (or mock verifications I guess).

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Tuesday, March 11, 2008

BDD in Practice - Mocking

Some of the articles on BDD put a heavy emphasis on mocking and outside-in development.

However so far the discussions on the BDD group seem to have left me feeling that when to mock is just as much of an issue in BDD as it is in TDD. Having said that as I try BDD I'm making sure I also spend the time to think about the ways I use mocking, just to formalize my thoughts.

Some of this is just my unordered thoughts, just stuff I'm thinking as I write the specifications using BDD. I've broken it down to sections based on the reasons I'm mocking.

Mocking As A Design Technique

I've been trying to do some outside-in style mocking as I go, I've discussed this in an earlier post but I am finding that thinking about collaborations (for Services at least) is quite an interesting technique. I've tried it in the past and didn't like it too much, but I think I'm now at a stage where I'll try to work it in to my normal practices.

I think I'm using the technique naively though. For example I ended up writing up-front mocking tests for an XmlFileBasedSender which takes in a DTO and ensures its packaged as XML and put in a suitable file. I blindly followed the technique but ended up with what I consider to be a pretty silly design:

public XmlFileBasedSender(IXmlFileNameProvider fileNameProvider, IConfigurationService xmlConfigurationService,
IFileSystem fileSystem, INotificationToXmlConverter notificationMapper)

To me INotificationToXmlConverter and IXmlFileNameProvider are just small lightweight strategy/helper/policy classes where as the other two are meaningful abstractions (especially as with them I'm wrapping built in .NET framework functionality). I'd think this style of constructor is more meaningful:

public XmlFileBasedSender(IConfigurationService xmlConfigurationService, IFileSystem fileSystem)

To be fair this isn't a problem with the technique, I've probably just gone overboard and at mockobjects.com Steve Freeman was good enough to point out that he might have just written an integration test for the service and might have encapsulated the little policy classes.

Of course even if I do just have XmlFileBasedSender create the instance of NotificationToXmlConverter in the constructor I might want to stub out NotificationToXmlConverter. In that case I'm stubbing for convenience rather than to use it as a design technique, but I think that's OK (especially since we use TypeMock).

I'm also not planning to use this technique all the time, I think state based testing is still often the way to go and that in many cases I'll stub rather than mock but that's not to say that this technique doesn't have its place. I especially liked using it in combination with integration tests. So after writing interaction tests for XmlFileBasedSender I wrote tests for each of the dependencies and then wrote a single integration test for XmlFileBasedSender (at which point I discovered I'd forget to create a class implementing IClock).

Finding the balance between mocking/state tests and between integration/unit tests is something I'll continue to think about, though presumably never coming to a conclusion on.

Mocking/Stubbing Out Dependencies

I needed to mock out calls to DateTime.Now and File.Create, using TypeMock to mock these would not be a good idea and anyway I'm happy enough to wrap in these cases (though wrapping DateTime.Now is a little irritating). There's lots out there about wrapping like this but essentially I ended up with tests like this (using string based mocking because I'm using the free version of TypeMock for the example):

[TestMethod]
public void Current_time_retrieved_from_clock()
{
#region Setup Expectations

Mock mockClock = MockManager.MockObject(typeof(IClock));
mockClock.ExpectGet("Now", DateTime.Now);

IClock clock = (IClock)mockClock.MockedInstance;

#endregion

new
ClassUnderTest(clock).DoSomething();
}
Technically I guess this is mocking for design, but even if I wasn't using mocking as a design technique I'd still need to wrap the file system and clock just to allow me to stub them out.

Mocking To Make Granular Testing Easier

ClientMapper uses a ClientFeeDestinationMapper so I've written tests for the ClientFeeDestinationMapper and then written one test that proves that the ClientMapper interacts with the ClientFeeDestinationMapper. This test was not about working out role interfaces so this is not me using mocking as a design technique and I just used TypeMock to mock out the concrete ClientFeeDestinationMapper.

One problem with this is that the tests (including the state ones) are very granular so any change means re-writing them. For example I plan to try using Otis (XML based object-object mapping) again, at which point ClientFeeDestinationMapper will probably disappear and ClientMapper will do everything (everything being kicking off the mapping process). Now in order to do that I first need to re-write my tests, which is a pain but not really related to the fact that I'm mocking or to BDD.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Wednesday, March 05, 2008

BDD in Practice

As I'm trying BDD I plan to write about what I'm finding, more as a way of organizing and recording my (current) thoughts than anything else.

Stories

For now I'm ignoring the story based approach to BDD, I still think it's probably going to be useful but I'm not sure I'm yet in a place where I can take advantage of it so I'm just going to focus on the specification style. Doing it this way is also simpler because in my view the specification based approach is just "better TDD" but the story based approach seems to me to be a bit more fundamental and affects more than the developers.

Naming Style

I've gone for this style of test class/method naming:

class When_mapping_a_customer

Name_is_mapped()
...
class When_grouping_related_domain_changes
All_changes_for_an_entity_are_grouped()
...

I'm enjoying naming tests in this sort of style, I've toyed with a few other approaches but this one has so far kept me happy as the class/test names are not too long but they are quite expressive.

I've taken out all the "should_" from the tests because it felt like noise especially when I viewed the list of test names in the IDE.

Of course this is very similar to the approach others have specified, including Agile Joe and there will certainly be better naming schemes around.

BDD (Astels Style)

Some seem to see BDD as primarily being about making it easy to trace a specification (test) back to its context. You start out with a context (small test fixture for a particular case) and then write your specifications, most of the code ends up in the test class setup method and the tests themselves are nice and small. You don't just end up with one big CustomerTest class full of tests that require different fixtures or which are for different features.

I do find that BDD's style of having lots of test classes (small fixtures) and attempting to have one line of code in the specification (test) method can make it easy to understand what is being specified.

It's not all good though, one of my colleagues points out that he likes to see all of the code in the test method.

We were also slightly worried by the fact that the specifications for a class end up fragmented across quite a few files, which is fine but you might have some fun finding the specification for behaviour for a particular class in a large code base. I'm getting around this at the minute by tagging the fixture classes with a [Concerning("AccountMapper")] as discussed by Agile Joe, you can then search for the class name and find all the specifications. Not very advanced though, but then again it will improve if tools come in that support the BDD style.

Oh and Brian Donahue has a post on the same sorts of issues so I'm not alone in think about this, and I'm sure they are issues that many other people are dealing with.

At the moment I'm not using any special framework for these specifications at the moment, which I think is a valid choice (for now). I'll probably look again at the specification side of NBehave and at SpecUnit.NET but it seems too early to be using either on commercial projects at the moment.

Initially my reaction was that this is really just TDD with a test class per fixture policy that focuses on really small fixtures. It hardly seems like a fundamental change, but having done it I think the combination of naming and small test fixtures is quite useful and could (perhaps) lead to people doing TDD "properly".

Team System

This is probably only interesting to a few people but there are issues with using these approaches in Team System. Nothing major but annoyances.

For example you cannot (as far as I can see) re-alias [TestMethod] to be [Specification]. Also the test list window is ridiculously constricting and there is (so far) no support for integrating other test runners into Team System.

There may be workarounds for some of these issues, for now I'm ignoring these topics though and just doing the best I can.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Thursday, February 28, 2008

BDD Forum

Agile Joe has setup a BDD group on Google Groups. There is also a thread on BDD at the ALT.NET forum right now.


Oh and there is also a dead Yahoo BDD group.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Wednesday, February 20, 2008

BDD and Outside-In Design

I've started using NBehave specifications to try and work out how BDD can affect the way I work.

As I touched on in my previous post. I'm hoping to try and find answers to my questions and the first one I wanted to deal with is how to best use BDD as a way of getting outside-in design.

I'm going to give an example of two approaches to using outside-in design with BDD, first though I'll explain what I'm testing:

SUT
I'm writing a Windows Service that will do the following (initially):

  1. Pick up unprocessed messages describing events related to domain classes.
  2. Go through each message in turn.
  3. Take the message and convert it to an XML document
  4. Send the XML message to our integration platform (BizTalk).
  5. Mark the original message as processed.
  6. Look for steps 3-5 until done.
This is a very much a technical piece of work but I don't see why BDD can't be used for such a task.

Story Definition
I'll define this overall story in NBehave syntax as:

story
.AsA("...")
.IWant("all domain event messages to be processed")
.SoThat("we send them to the integration platform");
Simple Test
To get going I want to start with a single simple test:

  1. Load the single unprocessed domain event message
  2. Create the XmlDocument describing the event and domain object.
  3. Send the XmlDocument.
Mock Style
The first way I think you can use BDD for high-level testing is something like the approach from Mock Roles, Not Objects:


[Test]
public void We_process_change_X_to_Y()
{
DomainEventMessage message = CreateMessageForAccountActivation();
_testMessages.Add(message);

#region Setup Expectations

XmlDocument emptyDocument = new XmlDocument();

Mock mockMapper = MockManager.Mock(typeof(AccountEventMessageMapper));
mockMapper.ExpectAndReturn("ConvertToXmlMessage", emptyDocument).Args(message);

Mock mockMapperFactory = MockManager.Mock(typeof(DomainEventMessageMapperFactory));
mockMapperFactory.ExpectAndReturn("GetMapper", new AccountEventMessageMapper()).Args(message);

Mock mockMessageSender = MockManager.Mock(typeof(XmlMessageSender));
mockMessageSender.ExpectCall("Send").Args(emptyDocument);

#endregion

story
.WithScenario("processing single event message")
.Given("there is a single unprocessed message relating to an X", MockRepositoryToReturnMessages)
.When("we process the event messages", ProcessMessages)
.Then("an appropriate Xml message is sent", VerifyExpectedCallsWereMade);
}
Its worth noting here that I'm using TypeMock (and only features from the free community edition) and not injecting in the dependencies so I'm not strictly sticking to the approach that the mockobjects guys push for. Having said that I am thinking that this is certainly a situation where I will be bringing in DI/IoC.

So what do I think of it? I guess this test is useful, it definitely made me think about the collaborators. To get the test to pass I have to put the followinge code into the SUT:

IList unprocessedMessages = new DomainEventMessageRepository().GetAll();

AccountEventMessageMapper mapper = DomainEventMessageMapperFactory.GetMapper(unprocessedMessages[0]);

XmlDocument xmlDocument = mapper.ConvertToXmlMessage(unprocessedMessages[0]);

new XmlMessageSender().Send(xmlDocument);
This seems like a good initial design (ignoring names of classes/members and possibility of DI). Having said that I'm not convinced that I wouldn't have come up with a design as good or better if I'd just relied on normal state based testing. Mind you at least with this approach I have come up with a list of requried collaborators early which is useful.

Now down to a problem though, although this test now passes my SUT does nothing because the collaborators all have do nothing implementations. This means that we're out of luck if we're expecting this specification to act as our acceptance criteria.

State Testing
Lets look at what I might do for a state based test:

[Test]
public void We_process_change_X_to_Y()
{
story
.WithScenario("processing single event message")
.Given("there is a single unprocessed message relating to an X", CreateAndSaveMessage)
.When("we process the event messages", ProcessMessages)
.Then("an appropriate Xml message is sent", AssertCorrectXmlDocumentProduced);
}
In this case the methods being called would probably be real implementations or at worst would use test stubs/spies. So I'd be thinking that CreateAndSaveMessage would create a real DomainEventMessage and would save it to the database.

So how do I get this test to pass, the truth is it will take me a while. I'll need to implement all the collaborators fully enough to handle this simple case (single message being processed) and I need to define the expected XML document before starting the work.

The good bit is that once I'll know that the system is handling the one simple case, which makes it a useful acceptance test.

Summary
I actually think that for the problem at hand both tests are good.

I don't rate the way most people use mocks, it often just ends up in unreadable over-coupled tests that are difficult to follow. However in this case we're showing high level collaborations that are indeed meaningful. I question the value of always thinking about all of the collaborators upfront but in this case it could be useful.

How do I apply both types of tests though, the options I'm going to try are:

  1. Write Both - Since I'm not sure I need that many tests that show the collaborations this could work.
  2. Write Mock Ones And As I Implement Remove The Mocks - I'd write a mocking test and as I write the real collaborators I'll go back and replace the mock implementation with the real one. Once there is no mocking in the test I'm done.
  3. Avoid Mocking - This is the approach discussed in this NBehave thread.

Initially I might go for the first approach, writing a few mock/behavior style tests but mainly writing state ones.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Monday, February 18, 2008

BDD - What still confuses me

Although I have now begun to play with writing high level specifications with NBehave I must admit that I'm not getting much further with understanding BDD in general.

I thought I should put my questions into a blog post, I guess its more of a brain dump than anything else though.

Is BDD just better TDD?
Its tempting to view BDD as doing TDD well. In reality though there are lots of ways to practice TDD but BDD is slightly more specific, such as the way it drives for an outside-in approach.

Having said that I think you can use BDD without buying into the whole Mock Roles, Not Objects approach but it is interesting that BDD is pushing that style of working. I've tried it out and it can have advantages but unsurprisingly it also has some serious problems.

Outside In?
Outside-in can mean many things but I like the definition from XUnit test patterns. Anyway even if you do practice outside-in you don't necessarily buy fully into the approach where you start with the GUI (or slightly below) and mock your way to all your collaborators (as described at Wikipedia or Mock Rokes, Not Objects).

If you practice DDD then you probably focus on the domain early, often then using classicist style testing practices (I've blogged about this before). If you do use mocking its probably when testing services and your probably not using it to definite ISP compliant role interfaces (or maybe you are, is it working because I am interested).

I think you can also find value in outside-in testing but this time starting from the public interface to the domain/application. You can start with a high level test and then start using TDD for the details, as discussed here. Once all the code is written. That doesn't preclude you using Test Spies or Stubs where appropriate, but it does mean that you don't need to jump directly into mocking which can lead to fragile tests.

If you do believe in mockist style testing, defining collaborations and going from there, then the high level BDD tests are a good place to do it however because thats the place where you will be thinking of high level interactions between entities/services/factories and so on. Showing those interactions in the tests could have some value, though whether you extract role interfaces is another issue.

Having said all this I do think you need to be thinking about/defining the GUI at the same time as working on the domain model to avoid overcomplication. For example you may implement a complex object hierarchy in the domain when for this version of the software something simple would have done. I've been bitten by this before, but I also think that starting from the GUI and working downwards is not the way to define a domain model. In my experience you usually need to do both GUI based work and domain work early on.

There are smart people who use outside-in testing in ways that I have no experience of (see this TDD thread which was a real eye opener for me, emphasizing just how differently people tackle testing/design).

High Level or All Levels?
For me the most exciting idea is writing high level BDD tests for two primary reasons:

  1. Stories - Lower level tests are less likely to be driven by stories from the stakeholder.
  2. Refactoring - High level tests are the ones that will provide benefits because they will be more immune to refactoring.
So can you use the same style for lower level specifications, I guess so but I haven't tried it yet and I'm not sure that it will work quite as well. If you do use it for your lower level specifications then I'd question whether a framework like NBehave is the best choice:

listStory
.AsA("developer")
.IWant("my list to behave correctly when items are added")
.SoThat("I can use it in my software");
This obviously isn't how you'd do it, but I'd be thinking that if you do use BDD at this low level then you are perhaps better just writing BDD tests without using something like NBehave (as shown on the wikipedia article of ListTest and by Jimmy Bogard in Converting tests to specs is a bad idea).

Can you use BDD for infrastructure/integration work?
NOTE: Here I'm talking about higher level (Scenarios, or Application Examples) specifications.

Ultimately everything you do is user driven but some problems make it difficult to tie your work back to a story.

For example my current project is an integration with an external system. This is quite a lot of work and defining user stories can be tricky as the users are not going to be interested till the integration is complete. Thanks to some brilliant help on the XP forum, not least Simon Jones' post, I've managed to get user stories to work for such a task but it does involve a little bit of work.

However for such a project do BDD tests make sense? Take the current piece of this project, a Windows Service that the users don't even directly use. I'm trying to use NBehave specifications but it can get a little odd, for example using the NBehave syntax who do I specify in the "As A" part of the story? Really the users don't even care that the service exists, but to be fair for this sort of work I'm happy to think outside the box a little and I think thats fine.

So yes I do think high level specifications can work for infrastructure/integration tasks.

Based On User Stories?
We use user stories and so the idea of writing the high level specifications based on user stories is attractive and I think it is a valid approach.

It is worth noting that whilst behaviour-driven.org seems to indicate that use cases are a good source whats-in-a-story does explain that its just as applicable where other requirements techniques are used (which is to be expected).

BDD and the Ubiquitous Language
I originally thought that BDD aimed to define, or help in defining, the (DDD) ubiquitous language. Its hard to know though so lets look at how BDD is linked to a ubiquitous language in some of the main articles:

  1. Wikipedia - "Behavior-driven developers use their native language in combination with the ubiquitous language of Domain Driven Design". I have no idea what this means, is it using the DDD ubiquitous language in the tests or are we saying that BDD is forming ubiquitous language for writing specificatons?
  2. Introducting BDD -Here BDD is the "ubiquitous language for the analysis process itself".
  3. Whats in a story -No mention.
  4. behaviour-driven.org - "It aims to help focus development on the delivery of prioritised, verifiable business value by providing a common vocabulary (also referred to as a UbiquitousLanguage) that spans the divide between Business and Technology.". This seems to indicate that your BDD specifications are supposed to look use the ubiquitous language.

As far as I can see there is absolutely no consistency in what the different sources of BDD mean when they talk about the ubiquitous language. I also think that taking the term ubiquitous language and using it outside of the context that DDD provides is unnecessarily confusing.

So what if the specifications are written in the ubiquitous language?

NOTE: This discussion only really applies to the higher level tests against your domain model, I don't think lower level (implementation detail) or infrastructure tests are going to be written in the ubiquitous language.

As discussed before according to behaviour-driven.org BDD:

...aims to help focus development on the delivery of prioritised, verifiable business value by providing a common vocabulary (also referred to as a UbiquitousLanguage) that spans the divide between Business and Technology."...

This sounds good and if I'm writing the tests then I will use the ubiquitous language. However if I'm doing BDD properly then I'll have others involved:

  1. BDD Process - "A SubjectMatterExpert (typically a business user) works with a BusinessAnalyst to identify a business requirement"
  2. Whats in a story - "the stories are the result of conversations between the project stakeholders, business analysts, testers and developers. BDD is as much about the interactions between the various people in the project as it is about the outputs of the development process."
So my question here is whether I'm expecting my user stories text to be written by people outside the development team? If so is it the users or the domain experts? If it's the former then I do not expect them to be in the ubiqutous language, if its the latter then I would.

As discussed above my own view is that in many cases user stories will feed into the BDD specifications. So do I expect user stories to be written in the ubiquitous language, not really and for these reasons:

  1. Different Audiences - Our users are not necessarily our domain experts and even if some of them are we probably have some who are not. Having domain experts write the user stories is not good (been there, done that) and having the users define the domain model is no better (too simplified). I thus think that expecting the users to understand the ubiquitous language, which probably has little to do with their day to day job, is unreasonable.
  2. Clutter - Stories are there to specify the behavior the user wants. With this in mind I'm not sure that cluttering them with domain model details is any more useful than including GUI details in them. Does a user care what model you put in place, probably not and I'm not sure we should expect them to.
  3. Evolving Language - You are also likely to evolve your ubiquitous language as you learn more about the domain, probably resulting in it becoming more complex. The question would then be whether you build this complexity into the user stories, I'd argue that doing so will just confuse things.

Thats the way I see it for user stories and offhand I can't think why this wouldn't apply equally to BDD. So I'm not seeing BDD affecting our ubiquitous language all that much, I think instead when writing user stories we should aim to use the language of the users.

Obviously if your domain experts are involved in writing the BDD specifications then using the ubiquitous language will be more attractive.

Anyway Greg Young has two superb posts on this namely BDD and the Shared Language and BDD and the Shared Language: The Stakeholder.

So In Conclusion...

BDD is many things to many people and although some people are trying to tie it down I'm not sure it will work.

Unfortunately although I think it is positive that there are so many ways to describe BDD I do find that in some cases (ubiquitous language) it is unnecessarily confusing.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Monday, February 04, 2008

Developer Testing - Discussion at ALT.NET UK

I thought I'd blog about some of the topics that were discussed at ALT.NET UK, or more correctly my views on those topics.

Styles Of Testing

I've blogged about the fact that I tend not to use interaction testing much. I find interaction testing can result in overspecified software and sometimes in tests that are hard to read. To be fair some of this could be countered by better use of mocking, for example diffrentiating between mocks and stubs (or Stubs and Expecations if thats the terminology you prefer), but state based testing is still my preferred approach especially for the domain model.

In the disucssion of mocking at ALT.NET UK it seemed that most of the attendees agreed that we are now overusing mocking. Whilst there was little disagreement with the idea of stubbing/mocking in some situations (e.g. between layers or domain modules) most people did seem to think it was dangerous if not used carefully.

Ian Cooper has blogged about this topic too.

Granularity

What granularity to test at, something that constantly irks me. To some people unit testing is always testing a single class, I've always thought that you can use unit tests for (small) groups of classes. In particular I do this when I have a helper class that I've extracted out of the class I was previously testing.

There are advantages and disadvantages to testing groups of closely related classes together though. The main advantage (especially early in design) is the tests can withstand refactoring and the main disadvantages are that they can be more complex and don't have such good defect localization.

Anyway Ian Coopers blog entry sum up my views on this entire topic. We also discussed whether to move/copy the tests down to the extracted class when you use extract class refactoring.

I'm totally inconsistent on this, I sometimes test against the extracted class and sometimes leave the tests at the level of the class I extracted it from.

Design For Test or Design For Design

The topic of design for testability came up a lot, though not in the way you might expect!

I've never believed design for testability is necessarily a good idea, I've blogged about this topic in a couple of posts before including here and here.

I don't believe there is any good substitute for thinking about your design. Sometimes designing for testability, especially if you favor lots of mocking using a traditional mocking tool, does bring lots of decoupling it's not necessarily as good as focussed decoupling.

Anyway I knew Roy Osherove was no longer recommending designing for testability and so was expecting a lot of disagreements around this topic. In actual fact though there wasn't much disagreement on the topic.

End To End Testing

At one session Tana Isaac discussed Watin which can be used to write tests for your GUI. The discussion covered whether GUI testing is a good idea because it can be more trouble than it's worth. However Tana pointed out that the tests they are writing are not only acting as good specifications but are not at all flakey and indeed are rarely being modified.

Others also mentioned the Web testing functionality in VS 2008, which apparently is far better than what was in previous versions.

The general discussion fitted in with the contributions that Nat Pryce made to an interesting TDD thread. Nat sums up the way he tests in this post.

All in all myself and John both came away thinking that we needed to look more at Watin and end-to-end testing in general.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

BDD - I think I'm finally getting some understanding

Nick Hines from Thoughtworks led a really good session on BDD at ALT.NET UK. The session clarified a lot of things for me, though as always after a bit of thought I am left with plenty more questions so I thought a blog entry was in order.

What Is BDD
My initial experience with BDD was Dave Astels doing a videocast about it. Better TDD and focussing on design were the name of the game. This made sense but when I started looking into it more I got a bit lost. The documentation seems to focus on the influence of DDD and the use of interaction testing. This confused me a bit as unless you practice need-driven development its questionable whether you are using interaction design as a domain design technique. I was also confused as to how BDD fit in with DDD, other than both sharing the idea of a ubiquitous language.

Anyway the discussion clarified the fact that its fair to view BDD as better TDD and it has little to do with need-driven development (though I guess you could use them together). It also doesn't specify that you must be using interaction testing.

Where to use BDD
We also came to the conclusion that these tests were quite high level, more influenced by users (user story acceptance tests) or a business analyst. I'm thus not clear that they would influence the domain design other than at a shallow level as your users are normally not your domain experts. This is probably what Greg Young means when he talks about BDD being used to for a shared language which may be distinct from the ubiquitous language.

Practically this probably means writing these tests against high level domain entities or your application/service layer. The discussion did cover whether you then take the BDD tests into the domain and indeed right down to hidden implementation details. I'm still not clear on this but if we are using BDD tests as specifications then starting out with detailed high level specifications isn't a bad idea, it gives us a good way of specifying acceptance criteria.

More Questions
The question is then how detailed to make these high level BDD tests. They have to be quite detailed and comprehensive if they are acceptance tests but if you make them too comprehensive then you are going to end up testing the same things at multiple levels, initially with a high level BDD test then with more detailed "unit" tests.

This seems attractive to me though, Jimmy Bogard has a great post about how he tried to make sure his BDD tests are somewhat immume to refactoring (changing implementation).

Other Links
Ray Houston is one of many people blogging about learning BDD, including this really interesting post.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

Sunday, December 30, 2007

BDD/TDD - What Drives The Domain Design

In view of the discussion of BDD[1][2] I've started to look at the way we specify/test our domain model. A great promise of BDD is that your tests will drive the design of your domain model and that the tests themselves will help explain the design of the domain.

My efforts to get to the essence of BDD have left me very confused and in an effort to better understand BDD I actually went to the Test Driven Development Yahoo group. I've been subscribed to it for a while but I'd never realized how good it is. Well informed discussion and heavyweights like Ron Jeffries/Kent Beck wading in. Great stuff and seems to me to have a similiar feel to the DDD group.

Anyway I came across one particularly useful thread. It doesn't really cover BDD directly but it does cover state/interaction testing and how they influence the way you design. In particular it contains a couple of great posts including this one which tries to get the to real essence of interaction and state testing and the way they affect your design.

I was already well aware of the difference between state and interaction testing but this single post summed things up very nicely and reminded me of a few things.

Personally I refactor, including to patterns, a lot. As I do I find my code changes massively which affects the way I test. Let me give you a representative example...

Example - State Testing/Refactoring Driving The Design
We need to allow people to debit Accounts in our system, a test to kick off this work might be

Account sourceAccount = ...;
Account targetAccount = ...;
Money amountToDebit = ...;

Money originalValueTargetAccount = targetAccount.Balance();
Money originalValueSourceAccount = sourceAccount.Balance();

FundsTransferService.Transfer(sourceAccount, targetAccount, amountToDebit); // code under test

Assert.AreEqual(originalValue - amountToDebit, account.Balance);

I'm not saying this the exact test I'd start with but its representative of the sorts of tests I'd be writing. This is a pure state test and in Ron Jeffries terminology is testing functionality not sequence.

As I go I'd be writing more and more tests and more and more code. As I went I'd refactor and after a while the method may be delegating to Specifications, Rules, Method Objects, Strategies, Entities, ValueObjects, Factories and other classes to do its work.

Some of the new classes will merely exist to ensure the code reads well (pure fabrications in Larman terminology).

As I extracted these pure fabrications I probably wouldn't change the tests, leaving them at the level that they started at (FundTransferService). I could change the tests to be tests specific to the new rule though. I'd just extract the code, ensure the tests passed, refactor the tests, ensure they passed...but then pure fabrications are very much open to redesign at any time so I'm not sure it makes so much sense to write tests for them specifically (questionable?).

Anyway what this means that I'm doing top down development (starting at public interface to the domain) but I'm not using stubbing or interaction testing, instead I use state testing and evolve the code and refactor a lot until I'm pretty happy.

Alternative - Interaction Tests Driving The Design

So the question is what is driving me to change the design, if I was doing proper interaction testing then I would be defining the interactions and then writing the code to fulfill it.

I could probably do this for the high level interactions, for example between entities. I'm not sure I want to include that information in every test but I could use it as a design technique and encode it in a few tests. This is quite high level interactions so I avoid the risk of overspecified software.

Ultimately I would still need some state tests (see this thread for a good discussion of the reason you still need state tests) but I'd be using interaction testing to drive my design.

However as I say I find a domain model is filled with all sorts of little domain classes that only exist because we chose to refactor the code to make it read better, these classes are not necessarily part of the ubiquitous language and are purely an imeplementation detail (they are pure fabrications).

Making interaction testing work for these pure fabrications seems to me to be a bit of a bad idea, these classes exist because of refactoring and I cannot plan for the interactions with them upfront.

Maybe if I stick to only using interaciton testing for the high level interactions, rather than interactions with pure fabrications, I'll get the benefits of interaction testing without the costs. I think thats what I'll try next.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone