Coding and Dismantling Stuff

Don't thank me, it's what I do.

About the author

Russell is a .Net developer based in Lancashire in the UK.  His day job is as a C# developer for the UK's largest online white-goods retailer, DRL Limited.

His weekend job entails alternately demolishing and constructing various bits of his home, much to the distress of his fiance Kelly, 3-year-old daughter Amelie, and menagerie of pets.

TextBox

  1. Fix dodgy keywords Google is scraping from my blog
  2. Complete migration of NHaml from Google Code to GitHub
  3. ReTelnet Mock Telnet Server à la Jetty
  4. Learn to use Git
  5. Complete beta release FHEMDotNet
  6. Publish FHEMDotNet on Google Code
  7. Learn NancyFX library
  8. Pull RussPAll/NHaml into NHaml/NHaml
  9. Open Source Blackberry Twitter app
  10. Other stuff

TDD - It may be driven, but it's not exactly directed

As some of you might know, and this blog will attest, I've been talking about doing open source work with FHEM for some time now - around 3 or 4 months now I'd guess.  As of yet, nothing's been published, and this isn't good.  I'll be honest, there's not been a ton of work going into this project (around 5 to 10 hours a week), but still, 3 months and nothing to show for it?  What the hell!?

When I think about it, there seem to be two big reasons for this this, the first I'm going to talkabout in this post, and the second in an upcoming post.  Where my testing problems are concerned, to spoil the ending a little, it does involve BDD with Specflow, but we'll come to that.

TDD (Test Driven Delusion)

The first few weeks were all good - I was just getting into TDD, and this would be the first project to use it in anger from the start. People warned me of some of the pitfalls that were coming, particularly around architecture, but I just ploughed on. In my mind, the mantra "red, green, refector" - I'd read a few of the TDD katas, it looked pretty straighforward.

My first test, the little bar goes red.  I quickly plug in the bare bones of my class under test with canned responses, the test goes green.  This is the only class in my project, so the refactoring's simple - tidy up a few names here and there, done.

The second test goes in much the same fashion, it's so quick, everything seems to lucid, I'm getting some good feelings about this code - it'll be solid, reliable, it'll just work and I'll never have to worry about it again (Telnet doesn't change, right?).  Sadly as subsequent tests were to prove, this feeling wasn't going to last.

Lean?  We don't need no stinkin' lean!

My next class has the responsibility of getting devices into and out of my telnet connection.

This class needed a little more work to setup and test - suddenly I have dependencies to mock, and I have to get all the canned responses prepared for my mocks. I'm looking at the XML data that Fhem is giving me and I start using XPath to pull out the fields I'm interested in, I notice that I'm actually writing a basic XML-to-object mapper.

Hey - wouldn't it be cool (alarm bells should be ringing at this point...) if I created a generic XML to POCO mapper using lambdas and XPath and fluent notation? Bear in mind this potential for awesomeness has popped into my head about 1 or 2 weeks into the project. This idea then proceeded to mushroom and soak up the proceeding two months of the project. Finally I take a step back and realise I don't actually need any of this functionality yet, and I end up ripping it out of the solution.

Don't get me wrong, I don't totally regret this two months.  After all, isn't one of the great things working on open source that you can take the time to do things RIGHT?  I've stashed this work to one side, so if in the future the app drives me to need this flexibility it's there.

To sum up the problem - when I've practiced TDD to date, I've worked in a bottom-up fashion.  I TDD the parts of the repository layer I think I'll need, from these I test and create the next layer up, and so on until I've got a feature that I'm ready to skin a UI around.  But this leads to a lot of playing around in these layers which may or may not actually make the cut.  It may be driven, but it's not exactly directed.

Behaviour Driven Development To The Rescue

I need some constraints - I need something that forces me to continually be looking at the end-user functionality I'm working on, and something that will stop me getting carried away with adding needless breadth to my lower application layers.

To help direct my testing, I've adopted SpecFlow and Selenium WebDriver to practice Behaviour Driven Development (BDD) on my UI.  I create a SpecFlow feature, describe what the application should do, and when I have a failing test I can practice traditional TDD to build up the layers beneath to make the SpecFlow tests pass.  Since I'm continually working towards a clear user-level test, I can focus on doing the minimum work required to get this feature delivered.

I'm also wondering whether class TDD should even be done in a bottom up fashion? Is there such a thing as classic TDD anymore, or are BDD and TDD such close offspring that they can be seen in code as the same thing? Still lots of questions!


Permalink | Comments (2)

Comments (2) -

Carl Phillips United Kingdom

27 April 2011 08:52

Carl Phillips

Did you try top-down TDD? Would that have achieved the same result for you?

e.g.
     1) Think of a feature, describe it in a user story
     2) Start with the UI abstraction (the view if using MVC or such) and TDD the crap out of it, mocking the model in the first instance.
     3) TDD the model for the feature, BUT ONLY WHAT YOU NEED RIGHT NOW.

russell United Kingdom

07 May 2011 12:34

russell

Maybe the discussion is all around what TDD actually means.

When I use the term, I realise I'm actually referring to a combination of NUnit and naming conventions that I see as traditional TDD practice. BDD is pretty much the same use of NUnit but with a different set of naming conventions that draw out a different exploration of planned behaviour.

So in response to your question Carl, I think you've pretty much described BDD, just done without the Specflow tools that really aren't essential for BDD anyhow.

If you're asking about testing from the UI vs testing from the view abstraction, I'm actually doing both - the view abstraction tests are what I run locally simply because I can inject my Moq-based dependencies, whereas with UI automation I currently cannot.

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading