Showing posts with label Unit Testing. Show all posts
Showing posts with label Unit Testing. 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 13, 2008

Test Data Builder and Object Mother

I've been meaning to write about this topic for a while because I think correct use of these two patterns can make a big difference to tests for any moderately complex domain model.

I'm not going to discuss the details of the two patterns themselves because there's already a lot of good content out there about them (see links at end), instead I'll discuss my impressions of them.

Why Are They Needed?

For any moderately complex domain model you're going to have quite a few ENTITIES and VALUE OBJECTs and although you'd like to avoid a Web of associations you will have associations between them.

Thus when testing a Customer (ENTITY) its quite possible that you'll want to associate an Account (ENTITY) or Name (VALUE OBJECT) with it. However you don't necessarily want the creation/configuration of the Account/Name inside the test fixture:

  1. You probably want to reuse the creation code in other tests.
  2. You don't want the creation code adding complexity to the tests, complexity that the reader doesn't care about.

There are other reasons they can be useful, most of which relate to any type of Test Helper.

Application

So far my approach has been to use TEST DATA BUILDER for value objects and then OBJECT MOTHER for Entities.

VALUE OBJECTS validate in their constructor so if you try to use an OBJECT MOTHER you get a lot of methods and overloads. For example you'd have methods to create an Address with a specific Postcode, another to create it with a specific PostCode and town...it gets old very fast and that's why I think an EXPRESSION BUILDER based approach is preferable.

ENTITIES do not necessarily force you to provide all the data to them in the constructor so an OBJECT MOTHER is a good approach. I use a combination of the patterns described in the Creation Method article in the XUnit Patterns page (also see Test Helper page on same site). This works nicely because you can use a simple method on the OBJECT MOTHER to create an ENTITY (give me an active customer) and can then customize the returned Customer in the test method (for example by giving them a rejected order).

I have used TEST DATA BUILDER for ENTITIES too, in addition to OBJECT MOTHERs, however I've only done this a few times and they are quite specific. In particular these are very high level builders so they handle cases like "Give me a customer with a relationship to an account manager who works for the company Spondooliks". This case involves at least three AGGREGATES and the associations between those aggregates and we want to make that setup really readable, which either means putting it in a method in the test class or using a TEST DATA BUILDER (or both).

One thing to be careful of is relying on values of objects returned by OBJECT MOTHERs or TEST DATA BUILDERS. If you don't pass in a value and it isn't implied by the name of the members that you used then do not rely on the value in your tests because if you do they become overly fragile and complex. So if you call CreateActive on an CustomerObjectMother and don't pass in any data then its safe to assume that the returned Customer is Active but you cannot assume that the Customer has an Age of 28 (see Creation Methods).

Are They Evil?

Some argue that both patterns are evil because by creating real ENTITIES/VALUE OBJECTS you are going from writing unit tests to writing small integration tests. I'm more in agreement with Ian Cooper on this point and think its usually fine to use real domain objects in tests (within reason). However if you disagree then you can go ahead and mock out your ENTITIES but you'd still want to use TEST DATA BUILDER for your VALUE OBJECTS (see this test smell from the mockobjects guys).

We want to avoid using OBJECT MOTHER to hide design smells For example if our ENTITIES and AGGREGATEs are too large, too complex, are overly coupled, or have too many states then we could use an OBJECT MOTHER to hide the fact that these problems make the objects difficult to create. Eric Evans discussed this topic here and I handle it by trying to ensure that the OBJECT MOTHERs themselves are kept clean and simple, if they get complex I definitely consider that as a good indicate that there is something wrong with the design.

Another argument which I've heard is that OBJECT MOTHERs and BUILDERs add a lot more code to step through and make debugging tests more difficult. As it happens I rarely debug tests but if I did I either wouldn't step into the OBJECT MOTHER or BUILDER or I'd add the necessary attributes (as Greg Young does).

Object Mother Links

  1. Pattern - You can also get this PDF here.
  2. Martin Fowler
  3. Ward's Wiki
  4. Creation Methods

Test Data Builder Links

  1. Nat Pryce - Great series of articles on the pattern.
  2. Expression Builder

Several other people use slightly different approaches, for example this one is quite interesting and is a variation of the approach I've settled on.

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

Sunday, June 15, 2008

Interesting TDD Posts

Three interesting posts have appeared. They started with Michael Feathers blogging about The Flawed Theory Behind Unit Testing, definitely worth a read.

Steve Freeman replied with Test-Driven Development. A Cognitive Justification? which itself had some very interesting points.

Another reply is TDD, Mocks and Design which is also very interesting and focuses on the reasons the advocates removing getters/setters and itss effects on design/testing.

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

Saturday, June 07, 2008

Pex - "Fix It" or "Allow It"

It seems like when Pex generates failing tests the choice is between "Fix It" and "Allow It" and they do seem to do very different things so I thought it was worth mentioning what little I've found out.

I'll start out with this code in a Pex test:

[PexMethod]
[PexUseType(typeof(AuthorizationService))]
public void overall_behavior_correct(IAuthorizationService authorizationService,
Account source, Account destination, double amountToTransfer)
{
new AccountTransferService().Transfer(source, destination, amountToTransfer, authorizationService);
}

When I run Pex with this test it generates one passing test and some failing tests:

BeforeGetTestsPassing

The failing tests are showing me useful things, for example the SUT does indeed raise an exception if the source and destination Accounts are the same. If I right click on either of these issues I get two options:

Fix It

If I select "Fix It" on each of the automatically generated tests then Pex ends up updating the original parameterized unit test (PUT) to look like this:

    [PexMethod]
[PexUseType(typeof(AuthorizationService))]
public void overall_behavior_correct(IAuthorizationService authorizationService,
Account source, Account destination, double amountToTransfer)
{
// <pex>
PexAssume.IsNotNull((object)source, "source");
PexAssume.IsTrue(source != destination, "source == destination");
PexAssume.IsTrue
(source.Balance >= amountToTransfer, "source.Balance < amountToTransfer");
PexAssume.IsNotNull((object)destination, "destination");
PexAssume.IsNotNull((object)authorizationService, "authorizationService");
PexAssume.IsTrue(amountToTransfer >= 1.5, "amountToTransfer < 1.5");
PexAssume.IsTrue(((AuthorizationService)authorizationService).AllowTransfer
(source, destination, amountToTransfer) != false, "complex reason");
// </pex>

new AccountTransferService().Transfer(source, destination, amountToTransfer, authorizationService);
}

If I now run Pex again it will generate 0 tests from this code. I guess this makes sense, the PexAssumes are presumably telling Pex not to pass in certain values (such as null for source). However in the process I've made my PUT pretty useless and it does make me question the usefulness of the "Fix It" option in these sorts of situations, so "Allow It" must be the more sensible option in this case...

Allow It

If I select "Allow It" for each of the failing generated tests then my Pex test stays as it was originally but the following attributes are put into my assembly:

[assembly: PexAllowedExceptionFromAssembly(typeof(ArgumentException), "PexPlay")]
[assembly: PexAllowedExceptionFromAssembly(typeof(ArgumentNullException), "PexPlay")]
[assembly: PexAllowedExceptionFromAssembly(typeof(ArgumentOutOfRangeException), "PexPlay")]
[assembly: PexAllowedExceptionFromAssembly(typeof(InvalidOperationException), "PexPlay")]

PexPlay is the assembly I'm working in (the assembly that contains the SUT) and this seems to be indicating that if I get any of the specified types of exceptions anywhere in PexPlay then the tests should still pass. This is confirmed if I re-run Pex as it will generate the same set of tests but they now pass:

PassingPex

Problem is that the attributes are at too high a level for me to be happy, I'm not necessarily always happy to see those exceptions so instead of using PexAllowedExceptionFromAssembly I tried using attributes at the Pex test level which seems to work fine:

[PexAllowedException(typeof(ArgumentException)), PexAllowedException(typeof(ArgumentNullException)),
PexAllowedException(typeof(ArgumentOutOfRangeException)), PexAllowedException(typeof(InvalidOperationException))]
[PexMethod]
[PexUseType(typeof(AuthorizationService))]
public void overall_behavior_correct(IAuthorizationService authorizationService,
Account source, Account destination, double amountToTransfer)
{
new AccountTransferService().Transfer(source, destination, amountToTransfer, authorizationService);
}

Its probably worth noting how the PexAllowedException have effected the generated tests, here's one of them (MSTest):

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
[PexGeneratedBy(typeof(when_account_transfer_occurs))]
public void overall_behavior_correctIAuthorizationServiceAccountAccountDouble_20080607_120018_002()
{
Account a0;
a0 = AccountFactory.Create(0);
AuthorizationService as0 = new AuthorizationService();
this.overall_behavior_correct((IAuthorizationService)as0, a0, (Account)null, 1);
}
As you can see the test is marked with ExpectedException attribute which correctly specifies the behaviour I expect when I pass in a null Account.

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

Pex - First Impressions

Apparently the issues I was having with Pex (ClrMonitorFail errors) were caused by its interaction with TypeMock. This doesn't shock me as having used TypeMock for a while I've learned that any time anything odd starts happening disabling TypeMock is a good idea.

So I disabled TypeMock and started playing with Pex, first impression is that it looks great but my second impression was that the IDE integration seemed a little flaky. My IDE actually crashed many times whilst using it but after a while I learned what to click and not click :)

Anyway I thought I'd start writing down the little that I've found out about Pex in case it is in any way useful to anyone.

First Feelings

I did notice a few interesting things when working with Pex, the first is that it seemed like it c lull you into a false sense of security.

Seeing a whole loading of auto-generated tests passing is great but I quickly began to notice that I could modify the code under test in inappropriate ways and my tests weren't failing. This wasn't Pex's fault though, I just hadn't been thorough enough in telling it what to expect and once I applied more PexAssume values and a few more assertions I definitely felt safer.

Fix It Or Allow It

I found that I was getting some useful tests generated even if I was quite vague:

[PexMethod]
[PexUseType(typeof(AuthorizationService))]
public void overall_behavior_correct(IAuthorizationService authorizationService,
Account source, Account destination, double amountToTransfer)
{
new AccountTransferService().Transfer(source, destination, amountToTransfer, authorizationService);
}

The tests Pex was generating were to do with null reference exceptions and invariants that the SUT was enforcing. Obviously initially the tests were failing so I had to tell Pex what I expected the SUT to do in each situation. I could do this using either the "Allow It" or "Fix It" options from the "Pex Results" panel.

If I chose "Fix It" then I would tend to get the following:

image

My IDE would then close down, gah. However if I persevered though it would update the test, for example:

[PexMethod]
[PexUseType(typeof(AuthorizationService))]
public void overall_behavior_correct(IAuthorizationService authorizationService,
Account source, Account destination, double amountToTransfer)
{
PexAssume.IsNotNull((object)source, "source");
PexAssume.IsTrue(source != destination, "source == destination");

new AccountTransferService().Transfer(source, destination, amountToTransfer, authorizationService);
}

When I then ran Pex for this method again it wouldn't generate a test that passed in null for source or that passed in source and destination as the same objects.

The alternative to "Fix It" is to select "Allow It" it, when I did that Pex would put this attribute in PexAssemblyInfo.cs

[assembly: PexAllowedExceptionFromAssembly(typeof(ArgumentException), "PexPlay")]

This seems a bit brute force though, I don't want to allow the exception across the entire assembly so I probably need to do a bit more research.

Decimals

One interesting thing that I noticed is that when I setup my methods to take in decimals I got no tests generated, but if I changed the inputs to be doubles I did. Not sure what that's all about but again I need to do some more research.

Mocking

Ignore the layout of this test, its a mess, but I do like the easy way I'm able to specify that I want to use a mock of the authorization service using the PexUseType attribute:

       [PexMethod]
[PexUseType(typeof(MockAuthorizationService))]
public void transfers_correctly_between_accounts(IAuthorizationService authorizationService,
double intialInSource, double initialInDestination, double amountToTransfer)
{
PexAssume.IsNotNull(authorizationService);
PexAssume.IsFalse(amountToTransfer < 0);
PexAssume.IsTrue(intialInSource > amountToTransfer);

Account source = new Account(intialInSource);
Account destination = new Account(initialInDestination);

double fromSourceBefore = source.Balance;
double fromDestinationBefore = destination.Balance;

new AccountTransferService().Transfer(source, destination, amountToTransfer, authorizationService);

Assert.AreEqual(fromSourceBefore - amountToTransfer, source.Balance);
Assert.AreEqual(fromDestinationBefore + amountToTransfer, destination.Balance);
}

The mock service is in this form (see the PDF for more on this but I haven't truly had time to grok it yet):

[PexMock]
public class MockAuthorizationService : IAuthorizationService
{
public bool AllowTransfer(Account source, Account destination, double amountToTransfer)
{
var call = PexOracle.Call(this);
return call.ChooseResult<bool>();
}
}

When I run Pex over transfers_correctly_between_accounts it will actually correctly use an instance of MockAuthorizationService and will run a test where that service returns false, causing the transfer to fail as expected. Nice.

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

Thursday, May 15, 2008

Reusing Tests at Different Granularities

Pat Maddox has a superb post called Refactoring with Shared Example Groups which describes one strategy that Ruby programmers can consider when deciding how they want to change their tests when they extract a class/method in the SUT.

I'd guess you could use a similar solution in C# especially if you hooked into a test framework like Gallio, mind you it might be equally sensible to look at IronRuby for testing (longer term).

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

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

Wednesday, February 13, 2008

Domain Oriented Messages

Greg Young has a great post titled Mocks are a code smell.

As he explains the title is to grab your attention and although he does see mocking being overused, which is definitely my view and seemed to be the general feeling at the mocking session ALT.NET UK, the post itself covers a very interesting way of handling communication within the domain.


To be honest Greg's ideas and implementations of this pattern are more advanced than mine, and I know he uses it a lot more in his designs that I do, so I'm looking forward to reading his other posts on this topic.

Trying It Out - Start Simple

If you're daunted by the idea of going to a messaging approach then you could always start simple.

As an example I would say that what Greg is suggesting is just a more advanced version of the approach that I intend to use for dirty tracking within our domain. Messages are generated when domain events happen and these will be registered with a service that you get from a service locator.

This makes testing simple as you can just use a test spy (same approach as Greg seems to be using) but is also a design that I like in terms of lowering coupling.

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

Tuesday, February 12, 2008

Justifying Our Designs [IoC/DI/AOP/Auto Mocking Contaner]

There was an interesting thread on the ALT.NET forum called "AMC: Changes to the way we think".

Now I don't use the auto-mocking container so it hasn't changed the way I think but I did want to comment on some of the ideas on the thread.

Should We See All Dependencies In The Constructor?
A lot of people seem to think that seeing a classes dependencies in its constructor is important, the argument being that seeing this tells you a lot about the design of the class.

This is a compelling argument and to some extent I agree with it but it misses one key point, not all dependencies are created equal. A dependency on, for example, a domain service or a repository tells me more about how a class works than a dependency on a logging/dirty tracking service. The first is a meaningful part of the design, the second is just an aspect of the implementation.

You could also say that seeing all a classes dependencies doesn't necessarily tell you much about how it behaves, to know that you need to see its own behavior and the way it uses those dependencies.

I'd also say that this is a case where people argue about the improvements in design when in some cases we are only doing what we are doing to fit in with the implementation constraints of the tools we use. We need to pass the dependencies in so we use constructor injection, to mock we need interfaces (or virtual members) so we end up injecting interfaces. The end result is very decoupled but is it useful decoupling, if we started from scratch and did the simplest thing that can work (YAGNI) would this be the design we'd come up with? Probably not...

AOP
Dependencies from the domain, Ayende indicates that he prefers his domain classes don't depend on non-domain services.

I buy into this too but for things like dirty tracking of domain classes it can get difficult but this is where AOP can prove useful, in those cases you're domain classes might have a run-time dependency on non-domain services but I think this is perfectly accessible. We can also probably use test spies for these sorts of dependencies, which makes for conveniant testing.

Testing
To me the auto-mocking container is a good idea but two things worry me about it.

The first is that it couples your tests to IoC, which when I first read about IoC was seen as a bad solution. I guess you can put up with this though.

The second issue I have with it is that it hides the dependencies that aren't important to the test. It seems like we've exposed the dependencies in the constructor to allow IoC and to allow replacing them in tests. However this makes the tests harder to read so we introduce a component to fix that issue. It just seems like it might be worth taking a step back and re-evaluating before you use the AMC, after doing this you might want to go ahead and use it of course :)

"Bad Designs" Can Work
So our domain classes have few dependencies other than on other domain classes (not on any services outside the domain). Where there are dependencies they are through an interface to the service, you get the service from a Service Locator.

However have layers above this, including a coordination style layer that talks to repositories and the rest.

So how do we get the repositories and infrastructure services into the services in the coordination layer, choices would be:

  1. Extracted interfaces passed in to the constructor of the service - Pass in an ICustomerRepository (or rename the interface to give it domain meaning).
  2. Pass concrete classes into the constructor of the service - Pass a CustomerRepository in.
  3. Make the service methods static but pass in the dependencies.
  4. Get the required services from a Service Locator.

Which do we do, none. The service methods are all static and when one of these domain coordination services needs a repository/infrastructure service it just creates it.

Its not as decoupled as we could make it but it's clear and simple and the layer in question is quite thin. If we needed to decouple we could without much effort and so I'm quite comfortable with the design we have.

What I'm trying to say is that I sometimes think people take things too far and that sometimes you can couple things safely. Maybe tomorrow you will need to rethink, but maybe not.

This doesn't mean that I don't rate IoC/DI or decoupling in general, I do. However I like to be able to decide for myself how far to take it.

Coupling Code To IoC
This was one of the original suggestions and I don't particularly like it. If you don't want to see the dependencies passed in to the constructor then I'd say you should use a Service Locator (which could in turn call out to a container) or use the hub service style approach.

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

Saturday, February 02, 2008

Test Spy - Replacing Services When Testing The Domain

At the recent discussion of mocking at ALT.NET UK we discussed using test spies.

We actually make good use of test spies now and they have some advantages. Let me give you an example where they come in handy. Our domain classes occassionally need to contact external services, interfaces implemented by these services are put in the domain (seperated interface) with the implementations available to the domain using a Service Locator.

What do to when testing though, we have maybe 1% of the the tests where we need to setup a mock version of the service and the rest don't care about the service so they can run with a do-nothing stub.

However if we register a mock version of the service with the Service Locator and if we forget to cleanup propely then that mock service will affect other tests. Its also painful having to put the stub service back in after you are doing using the mock.

The solution, suggested by one of my colleagues, is simple. We don't ever mock the service but instead we use a test spy. We register the Test Spy with the Service Locator in a method tagged with AssemblyInitializeAttribute so it gets run before any tests in that assembly.

All the normal tests run normally, and if they in some way cause the system to interact with the test spy then the interaction happens totally silently, for example maybe the test spy logs the interaction by adding an item to an internal collection.

So what about the 1% of the tests that really want to test against the test spy (the tests that might otherwise have used a mock). Well in the test fixture initialization we reset the test spy then at the end of each test we ask the test spy what calls it received and verify that they were what we expected.

This works a treat, really simple solution that makes the tests very easy to write.

NOTE - When to call services from the domain
The comment from Andreas made me realize that I didn't say when I think a domain class should talk to a service.

Normally I avoid these sorts of dependencies in order to keep the domain code clean, simple and easily testable. However for cross cutting concerns like logging/dirty tracking an AOP based approach (see my PostSharp posts) where we introduce the code that calls the service is very clean.

In particular this works because for those cases we can have the domain class contact the (infrastructure) Service but we don't care about any return values, hence the applicability of a Test Spy.

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