Jul 31
Starting Down The BDD Path
icon1 Darrell Mozingo | icon2 Testing | icon4 July 31st, 2009| icon32 Comments »

Behavior Driven Development‘s (BDD) meaning has, until recently, skipped right past me. I’d read about it and used it heavily for a week during JP’s Nothin’ But .NET Boot Camp, but when it came down to really seeing the value in it over the normal bunch of tests per test fixture TDD style, well, I simply didn’t. The assertion naming with extension methods (value.ShouldEqual(10) vs. Assert.AreEqual(10, value)) and sentence-like test names (Should_calculate_the_sum_of_all_hours_worked vs Method_Intial_Expected) were pretty neat and we’ve been using them for a while now, but all the rest was lost on me. I mean, a whole class just for one or two assertions? Seemed like a lot.

That was, however, until I realized some of our test SetUp methods were literally several pages long. Sure, all of our tests after that were only a half dozen or so lines and it all totally made sense to us when we wrote it, but I found having to go back into these tests to add/modify behavior was proving difficult. I honestly feel the classes and the tests themselves were following the Single Responsibility Principal pretty good, but these few classes just needed a lot of context to set them up before checking the outputs. There wasn’t really an easy way around it – either we have the huge setup with shorter tests, or we have more fairly large tests.

Another example of the situation breaking down was a few of our test fixtures, where we’d have the SetUp method setup a context (which, again, was a bit large), but each test would slightly the context for its need. The result is needing to look in two places to get the whole picture of the context, and even taking into account some tests that would override certain parts of the context for their own needs. It wasn’t pretty.

While trying to figure out which pieces of the setup context applied to the specific test I was modifying, I knew there had to be a better way. While watching a presentation on InfoQ by Jeremy D. Miller, The Joys and Pains of a Long Lived Codebase, Jeremy talked a bit about how his testing strategy has evolved, and how he’d come to accept BDD after staying away from it. He talked about how important the context of a test was to understanding what it was doing, and how he resorts to copy & paste for parts of the context if he has to in order to keep it easily readable. That part really clicked with me, and I decided to give BDD a honest shot in our current project.

There’s plenty of existing BDD frameworks for .NET, including Machine.Specification, NBehave, Develop With Passion.BDD, and xUnit BDD Extensions, but I wanted to keep it simple for now as we integrate it with our existing project, and the other devs on my team had never used the syntax before (and I only had one intense week of exposure), so I didn’t want to clutter it up too much for the time being.

In light of that, I created a super simple specification base class:

public class SpecBase
{
	[TestFixtureSetUp]
	public void Once_before_any_specification_is_ran()
	{
		infastructure_setup();
		context();
		because();
	}
 
	protected virtual void infastructure_setup()
	{
	}
 
	protected virtual void context()
	{
	}
 
	protected virtual void because()
	{
	}
}

I wasn’t kidding – there’s not much to it at all. The infastructure_setup method allows me to create base classes for testing services/controllers/mapper, where I can setup our AutoMocking container and create the system under test as neeeded. For example, here’s the base spec class we use for testing our services:

public class ServiceSpecBase<INTERFACE, SERVICE> : SpecBase
	where SERVICE : class, INTERFACE
{
	protected RhinoAutoMocker<SERVICE> _serviceMocks;
	protected INTERFACE _service;
 
	protected override void infastructure_setup()
	{
		_serviceMocks = new RhinoAutoMocker<SERVICE>();
		_service = _serviceMocks.ClassUnderTest;
	}
}

The auto mocker (from StructureMap, in this case), just makes an empty dynamic mock for each argument of a given constructor. Our services generally take in a good half dozen objects, so this saves us from having to create them by hand (via something like var mockRepository = MockRepository.GenerateMock()). The system under test is then created after the automocker is initialized (I don’t generally like the generic “sut” variable name if I can avoid it – you’ll see I’m using _service for this class as the service is always the system under test for anything using this base class).

Here’s an example specification using this new SpecBase class:

[TestFixture]
public class When_hiring_an_unemployed_person : SpecBase
{
	private readonly Company _company = new Company();
	private readonly Person _person = new Person();
 
	protected override void context()
	{
		_person.IsEmployed = false;
	}
 
	protected override void because()
	{
		_company.Hire(_person);
	}
 
	[Test]
	public void Should_increase_the_number_of_employees_in_the_company_by_one()
	{
		_company.Employees.Count().ShouldEqual(1);
	}
 
	[Test]
	public void Should_mark_the_person_as_employed()
	{
		_person.IsEmployed.ShouldBeTrue();
	}
}

This example doesn’t really show how well BDD has started helping reduce the complexity of some of our tests by explicitly naming the context they’re running in and making them easier to read. As with every other example on the Internet, this one isn’t quite complex enough to really show the benefits, but I hope you at least catch a glimpse of them. I also realize this might not be “correct” BDD styling, and that I should be leveraging share contexts with a base class more (for that mater, I should be using an actual framework for this), but it’s serving the purpose well, and it’s a simple first step to introducing it to the code base and my team. It’ll evolve – always does.

Another great resource I found helpful was Rob Conery’s Kona episode 3, where he explains BDD and converts some tests to using them.

Jul 17
Crisis as Opportunity
icon1 Darrell Mozingo | icon2 Musings | icon4 July 17th, 2009| icon31 Comment »

I’m currently reading through Eric Evan’s Domain Driven Design. It’s quite a good read – a bit thick at times, but still very much grounded in pragmatism and real life. One smaller section really stood out at me recently, titled “Crisis as Opportunity”, and begins on page 325. Here’s a few of the more meaningful portions from that section:

“A period of steady refinement of a model can suddenly bring you to an insight that shakes up everything…Such a situation often does not look like an opportunity; it seems more like a crisis. Suddenly there is some obvious inadequacy in the model…Maybe it makes statements that are just wrong. This means the team has reached a new level of understanding. From their now-elevated viewpoint, the old model looks poor. From that viewpoint, they can conceive a far better one.”

Its something that’s happened to my team a few times on our current project so far – seeming like we hit a brick wall on an issue. Certain parts of the code base were having to be bended and twisted all sorts of ways to meet new requirements, producing far uglier code than when we first wrote it. These areas seemed to dragging us down, but the constant onslaught of requirements pretty much forced us to push through and find a better way.

Taking a step back from the situation provided a great view that allowed us to use some new understanding of the domain, our current code base, and where we knew it was heading in the not too distant future, to refactor for “deeper insight”, as Evans calls it. Introducing elements that were implicitly in the design as explicit objects and methods was exactly what we needed. The former problems areas were then much easier to work with, allowing new requirements to be added at a much faster pace.

I now almost look forward to hitting a brick wall when trying to add new requirements to our domain. It means our domain needs work and we could be on the cusp of a nice big ‘ol refactoring to gain more insight, and I love my insight.

Jul 1
2009 Goals – July Update
icon1 Darrell Mozingo | icon2 Goals | icon4 July 1st, 2009| icon32 Comments »

We’re half way through 2009. How am I doing on my goals for the year? Let’s see (comments in italics after each goal):

Books

  1. Code Complete – Steve McConnell (yep, I’ve never actually read it)    No progress.
  2. Patterns of Enterprise Application Architecture – Martin Fowler    Ordered and on my bookshelf.
  3. Domain Driven Design – Erick Evans    A bit over 100 pages left.
  4. Working Effectively With Legacy Code – Robert Martin    No progress.

Tools/Techniques/Processes @ Work

  • NHibernate and all its trimmings (FluentNHibernate, LINQ to NHibernate, etc), which I’ll need on a project here real soon.  Done, but still picking up stuff.
  • Actually move from CC.NET to Team City (last attempt didn’t go so well).  No progress.
  • Build a more robust build script and management process – including production deployment scenarios.   No progress.
  • Messaging framework, either MassTransit, NServiceBus, or Ayende’s new Rhino Service Bus if he’s able to release it in time for our current project.  No progress as we haven’t needed any yet.

Involvement

  • We have weekly meetings to catch everyone up on what we’re doing, but I want to present on an actual topic during at least 2 of these – and present in a way where the other development teams will see the use in picking up the presented tool/technique.    Our meetings are still halted, but I’m hoping to do an intro IoC/DI presentation if they ever start again.
  • Have at least one meeting of the CantonALT.NET group and see if it can ever get up on its feet.   No progress, but we have had a few Code & Coffee get togethers.
  • The two blog posts per month target John put out there seems doable, so I’ll borrow it 🙂    Pretty much on target.
  • At least 3 feature/patch submissions to open source projects.  No further progress past the last update.

Productivity

  • Trim RSS feed size by 1/3 (presently at 127, so trim it to at least 85) and cut time viewing it by half. I’ve gotten much better this past year at cutting through the useless stuff, but there’s still a lot there and it sucks up too much of my time.  Down to 103. Not too bad.

Once again, the reading is killing me. It’s not that it’s not interesting, it’s just time. Between a few magazines I read (some technical, some not) and projects around the house, reading time always seems to take a back seat. I’ll get into it for a bit and fly through the pages, but that “bit” is usually only a day or two, unfortunately. Lets see how the next two months go.

I’ll update again in the begining of September.