Wednesday, April 20, 2011

Baby Steps

We’ve been recently working on moving the legacy UI code to MVP.  This week has seen my focus move from doing some of the initial work, to a support role within our team.  So the focus has been on fixing live issues that we currently have within our system.  I might blog about the reasons I think we have these support issues in the future. 

As the week has progressed (it feels like a long week, maybe because it’s a short week!) – I’ve been getting more involved with a colleague who is now converting the legacy code to MVP.  It’s been extremely interesting pairing/mentoring the developer.  My colleague is quite new to MVP and test first approach so it has been interesting to see how focus can be lost quite easily – thinking about other sections of the system. 

I think this is to do with focusing on the problem at hand, not getting distracted by other issues and just solving the current red issue – the broken test.  Once this is green we can think about things which might be important or not be – i.e. how can we improve the current design and the current code base.  Or even add another test to highlight the current hacked – I’m very much of the ilk of doing the simplest thing to green.  Maybe I’m just plain lazy or like to KISS.  Maybe I want to ensure that my focus is on the smallest possible thing.  A former colleague always used to say, “I can only concentrate on one thing at once.” 

This has made me think about a number of things.  Developing software is hard; thinking about an entire system and its interactions is even harder.  Sometimes developers struggle to focus on their current problem and get distracted by something completely different (i.e. the entire system!). 

This is the reason it’s important to write tests first.  The act of writing the test focuses the mind on what it is we want the method/SUT to do, we can then focus on doing the simplest thing to get the test green.  Once this is done we then focus on refactoring.  We then repeat.  This ensures that we keep focused as we write the code – it’s a very nice rhythm, and very rewarding (amazing how seeing something go green gives me a thrill!!). 

I recently sent out the code kata that Roy Osherove put on his blog – the string kata.  It's interesting that the notes say ensure you do not rush ahead of yourself and do not scroll down.  Something any human being would want to do, we are thirsty animals for information and problem solving!  I know that some people might struggle with this!

I suppose this poses a couple of questions for me:
  1. Are we killing the inquisitiveness by stopping people from rushing a head, or just simply focusing the brain power of the individual/pair (I know that in a pair one will concentrate on the code, and the other on the design) on the problem at hand? 
  2. Do we currently struggle to focus on a single thing?
  3. Can the human brain multithread?!

Wednesday, April 13, 2011

Exposing Code Smells with Tests

I’ve managed to complete my other project within my original estimates – I will blog about whether visualising the work and the other approaches I took worked/helped next time!

Today’s task has been to start converting the UI layer of the main legacy system that our team maintains to MVP.  I’m not going to delve in to the reasons why we chose MVP; well I think we just decided that it would be the easiest path to getting the UI under test.  The team probably has more experience with MVP than MVC so it’s probably a wise choice! 

I’ve taken a relatively simple screen to start with, one that shows the notes on a specific Sales Order, allows some filtering, and allows the user to add an additional note.  Instead of delving straight in to the ASP.Net code and slotting tests around the existing functionality, I chose to simply abstract the current functionality in to the presenter.  This was all done using tests to drive the code.  Essentially the tests are what the code does “as-is”, so I suppose you could say that I let the current implementation drive the tests to a certain degree. 

As I started to increase the number of tests around my newly created notes presenter class, interesting patterns and problems with the existing code emerged.  Since I’ve become an advocate of a Test-First approach, I’ve noticed that code not written by tests doesn’t show problems – early in the development cycle.  I also think (maybe wrongly) that code doesn’t get refactored if you don’t have good tests – therefore ending up spaghetti-fied or just damn hard to highlight problems.

The existing code does a number of things:
  • Shows all the notes; Or;
  • Allows you to filter notes
  • Then displays the count of each of the types of notes
Now as the tests have grown I’ve found the existing code does the following:
  • Shows filtered notes/all notes
  • Then gets all the notes again to display the count of each of the types of notes.
The presenter should just get all the notes then filter based on the current filter criteria.  This removes the dependency on multiple calls for the notes.

The other thing I found was that the NHibernate ISession is used at quite a high level – with the Service (essentially the Model that I’ve been using for the Notes – it was in existence already) that I am calling to get the Notes.  The problem was that I had to force the ISession in from the Presenter.  This has made me feel really uncomfortable –a code smell!  I’ve had to mock the ISession object out for all of the tests since I am using constructor injection.  Really this dependency should be pushed right in to a Model. 

Thinking about it further (as I write this blog post) – it is probably about time to create a real model.  I thought I could have got away with using the existing note service for this purpose.  This in essence would be a model/fa├žade so I no longer have to mock the NHibernate ISession.

This is something I will endeavour to do on the next phase of development (i.e. tomorrow!).

I find it interesting that the things above highlight themselves after only writing a dozen or so tests.  It definitely backs up my thoughts on test-first development, and makes it even more crucial to write them all the time.  There has also been the added benefit that I’ve been able to fix a minor UI bug with the code that I’ve written.