Overview

I've long been a proponent of test driven development. Core to this is the implementation of patterns and unit test coverage. One of my favourite patterns is Model View Presenter (MVP) http://www.codeproject.com/KB/miscctrl/MVP.aspx. I particularly like the decoupling of the GUI layer from the business logic. Used appropriately I believe it offers very real business benefits particularly for complex screens.

However having lead a project for a trading application where I encouraged the use of MVP I spotted some real world disadvantages, wanted to share them with you and offer you another pattern I think works very well.

One of the stated advantages of MVP is that one can slot in a new presentation technology with almost no impact on the code base, whilst this is an honourable intention in my ten years of software development I have yet to see this emerge as a real requirement on any project I've worked on. Therefore I'm prepared to sacrifice this level of abstraction in favour of code clarity.

Keep it Real World

The nature of software development in this day and age is that it is often global and as such encompasses teams of differing abilities where communication is often not as good as it should be. A technical architect is therefore faced with a dilemma of whether to doggedly pursue what he knows to be the most architecturally pure design as opposed to that can be realistically delivered to the client's timeframe. In a nutshell I wanted a pattern that offers me a sensible level of decoupling of business logic and presentation, that is easy to cover with unit tests and is not overly complicated to implement, maintain or explain to new team members.

I stumbled over the separated presentation pattern at Martin Fowler's website http://www.martinfowler.com/eaaDev/SeparatedPresentation.html and was struck by its simplicity and elegance. If you've done any ASP.Net development you'll recognise this pattern as being similar to the concept of code-behind i.e. one file for the presentation of data and one for business logic.

Let us begin

The accompanying solution provides you with an example of the separated presentation pattern. It's the most basic of applications and simply retrieves a value from a make-believe database and displays it in a form. Should a user alter the data the colour of the text changes to remind them that this change has not been persisted. Upon clicking save the data is stored and the text colour changed back to its default.

Testing Times

In this day and age any application worth its salt should have a series of unit tests to ensure regression coverage. The world of unit testing is full of contradictory advice and competing factions at to how sensible testing should be implemented. In the same way that one given methodology does not suit all projects, in my opinion one testing approach does not suit all projects. However I'll offer up some suggestions as to how I test the separated presentation pattern and I hope these will be of interest, should you have a better approach feel free to share it.

Here are the basic principals I try to stick to when writing unit tests.

  1. Use a concrete object for non data source related operations
  2. Use stub/mock for data source related operations
  3. Do not change access modifiers on your classes to get tests working; you'll be compromising your design.
  4. If working with a stub object it should inherit from an interface and not a concrete class otherwise you'll end up altering the design of the concrete class
  5. With the exception of a small learning curve when first embarking on writing unit tests the amount of time a developer has to spend writing tests should be minimal.
  6. A bad test is worse than no test
  7. Constantly ask yourself "Does my test really add value?"

One of the features I really like about Visual Studio 2008.NET is the command line tool MSTest which offers a very quick way of running test cases and can be incorporated into a build script. When this is run one can see the results of our tests and also our application GUI appearing and disappearing as various test conditions are evaluated.

Lovely view

Typically unit testing focuses on the testing of the model. Normally testing of the GUI is either overlooked or handled by a third party piece of software driven by testing scripts. I happen to believe there is value in testing the GUI from within our testing environment and this can be achieved with a little bit of code. Not only does this ensure that the state of the model is correctly reflected in our application I've also noticed a tendency within Visual Studio .NET to drop reference to events from controls and our tests can easily catch these problems.

C# 3 also provides us with some coding short cuts that make it easier to tackle cross threading issues when performing GUI testing; specifically anonymous methods and lambda functions. There are comments highlighting this in the accompanying code.

Unlike third party, script driven testing products the developer is free to move controls around to their hearts content and as long as the names of the controls don't change all tests should continue to work.