Saturday, 26 September 2009

Subverting the source of justice

A post involving the use of subversion as my source control system? How could I not use that title? :)

Anyways, whilst I am the only developer working on my own personal projects, source control is still an essential tool. I may not need to sync my work with that done by other developers, but the version tracking that it gives is something that I don't want to be without. Additionally, as I am doing these projects to enhance my knowledge of various tools and best practices, getting a source control system in place is the first step towards being able to build a continuous integration server. The benefits here are far less obvious for a single developer project, but as a learning exercise it is very useful. At the start of a project seems like the best time to get this stuff set up too, so I can focus on getting decent build scripts that run unit tests, code coverage and other analysis all sorted out up-front, so I only have to make minor tweaks to my build as I go along the path of development, rather than try to set it all up further down the road and find things potentially more tricky.

As an aid to setting up my CruiseControl.net server I followed an article on dotnetslackers.com that is part of a series about building an entire website from scratch using all sorts of best practices, just the sort of thing that I want :) (linky). The author mentioned that he was using build 1.5.0.6184 of CC so i decided to use the same build rather than get the latest so I would encounter the same nuances that he did, unfortunately that idea didn't work out as well as I hoped, but I got it running in the end. I wonder how much smoother some of my past projects might have been had I discovered this stuff earlier.

Friday, 11 September 2009

TDD for free

Today was a good day. I was given a new project at work and in the spec that had been written up there was a comment that the functionality was fairly complex and so a test plan should be written up. This screamed to me as being the first chance that I might have to be able to introduce TDD practices in my workplace, and things went rather well on that front. My boss vaguely recognised the name of NUnit, but knew nothing about it. I explained the general principal of having a suite of consistent tests attached to the code that can be run quickly and easily to make any breaking changes instantly obvious and he was happy for me to give it a shot.

The only concern that he expressed to me was that of cost. Our department is what could be described as desperately underfunded. Developers are expected to provide a certain amount of IT support to the rest of the company, we are still using SQL Server 2000 for production databases, and we only have the free Express editions of the developer tools to work with. Anything that costs money is not going to get the go-ahead because we have none to spend. Fortunately there is some very good open source software in this area, so permission was granted.

In my investigations into TDD at home I have become accustomed to being able to run my tests in the IDE by way of tools like Resharper or TestDriven.Net. This was something that I was keen to continue with as having to switch back and forth between the IDE and the NUnit GUI is an added distraction, but the Express tools don't allow you to use any plugins. Fortunately I have recently been raiding the back catalogue of the Hanselminutes podcast and remembered Scott mentioning some open source tools that had sprung up around the Mono project, including an IDE called SharpDevelop. This has an integrated NUnit test runner, so I installed it on my development box and was off.

The next step in being able to do effective TDD was to get a mocking framework in place. I have had some experience with Moq at home on C# projects, but the reason that I chose it was because it is very specifically tuned for C# and the language of choice in my current job is VB.Net. Some googling indicated that it may be a little more tricksy to use effectively with this language restriction, in fact it seemed like all of the frameworks with the possible exception of TypeMock are C# focused to the detriment of VB.Net. I ended up deciding to use Rhino Mocks as there seems to be a lot of information on the web regarding it and because the .Net community has a lot of respect for Oren Eini so I feel happy using anything that he is involved in. With my IDE integrated test runner and my mocking framework in place I was ready to get started, and despite it being a bit of a slow start as I had a bit to learn about my new toolkit I am happy with the results of my day's work.

The biggest stumbling block that I have encountered with this set-up so far came up when I started my first mock. I was setting up a mock of my repository so that the business logic could receive a result for a data request. Using the Arrange, Act, Assert (or AAA) syntax, I needed to call Stub on my object. This is an extension method added by Rhino Mocks used to program the mock object so that it can respond as desired to certain requests made of it, and it takes an argument in the form of lambdas pointing to the method that will be called. For some reason this wouldn't compile. I was given a very short error message by the compiler stating that there was an issue with the Stub method, but it was not at all helpful. I spent a while trawling the internet for clues but to no avail. I finally decided to try compiling it in Visual Studio instead of SharpDevelop, I wasn't very hopeful about what the outcome would be as SharpDevelop will still be using the same MSBuild to compile it but it remained one of few options left open to me. Unsurprisingly I had the same error, but with one very important difference. The error message was MUCH longer. I can't remember the exact detail, but the essence of it was that I had some error in the construction of my lambda in the Stub method. SharpDevelop merely told me the outermost part was failing at compilation, but Visual Studio was giving me the trace of what was going on within it and so I was able to spot and fix the error pretty quickly. I switched back to using SharpDevelop at this point so that I could continue to use the test runner.

From what I have seen of SharpDevelop so far, it is not complete enough to entirely replace having a Microsoft IDE on my system, and this could become more of an issue with ASP.Net sites as the support for this is meant to be minimal and most of my work calls for ASP. However, it offers compelling reasons to use it alongside the MS toolset when restricted to just using free software. I'm happy to be able to stick to the full version of Visual Studio with the personal version of TestDriven.net at home, and having played with trial versions of Resharper and CodeRush & Refactor I can see how these could add a lot to my productivity which SharpDevelop will never be able to match, but it has certainly helped things along today and I hope to get more out of it in the future, especially as that would imply that the company is happy for me to keep on using a TDD approach.


Sunday, 6 September 2009

ToDos in code and my all time favourite thing in .Net ever of the week

In a recentish blog post, Jeremy Miller discussed his favourite way of marking up ToDos in code in such a way that it is very very obvious that there is still work to be done and where it is needed. Whilst I like the technique it is entirely dependent on working with unit testing frameworks and in my current role we sadly do not have any sort of testing in place. I'm hoping to try and rectify this, but for the time being I need a different option. This leads me to the first bit of technical stuff in my blog. Hooray.

Operating outside of TDD I also find that ToDo's close relative of slipping quick hacks into code to ensure that a particular path will be followed during my manual testing can be very handy. Both of these are things that need to be removed from code as soon as possible, they desperately shouldn't make it into production code, and should be as obnoxious as possible to make them easy to find and remove whilst being a very noticeable smell when they are present. Adding debug or trace output can easily be lost if the program is generally chatty and requires that code to execute to even show up. Just commenting it requires me to remember to search for issues that need removing, and a little typo could lead to problems being lost forever.

The answer that I have found to this focusses around the Obsolete attribute.

[Obsolete("HACK - This call is a hack that should be removed prior to release")]
public void Hack(string message)
{
Debug.Print(message);
}
[Obsolete("TODO - This marks a placeholder for work to do")]
public void ToDo(string message)
{
Debug.Print(message);
}

When compiled this will leave warning messages anywhere that the routines are called which is suitably obnoxious unless you have a project full of warning messages and that is a whole nuther problem. A double click of the warning message takes you straight to the code that called it meaning that locating the temporary hack or ToDo is quick and easy, and the mix of intellisense and compilation errors means that you're not going to lose something that you mistyped as TiDo or similar.

Marking the code as Obsolete feels a little kludgey, but it is the only attribute that has this behaviour and it can't be derived from to create something that fits more naturally. Of course, due to the temporary nature of how the routines are used there is an argument that any time they're added they are instantly obsolete, so I can cope with the slight dodgyness.

As such things are very useful, especially in an environment that doesn't allow for TDD or effective OO practices (most of the code for many of our company's apps is situated in the same file as the ASP markup, not even in an overly crowded code-behind, just with the markup) hence this is my all time favourite thing in .Net ever for this week (and in fact the last few weeks from when I started using it)


Coffee or Synergy

I had a plan. At the time it seemed like a good plan, but in retrospect I have decided that maybe it was misguided. In an earlier post I mentioned that a lot of the interesting tools in the .Net space originated in Java. Things like NHibernate and NUnit were significant over there but were also very highly regarded in .Net and were high on my list of stuff to learn. This led me to think that I should concentrate on just using tools that exist on both platforms so I might have a better chance at performing well were I ever to have to work on a Java project.

The thing is, I'm not likely to end up in such a situation, and whilst Java and C# syntax is obviously similar I think that I would have more issues to worry about than not knowing a framework that I may or may not be allowed to use. As I spend more time learning bits and bobs about some of these tools and best practices it has become obvious that there are synergies between certain products. Researching NHibernate shows that there is a strong relationship to the Castle project, even to the point that some of their binaries are included in the NHibernate distribution. I had been planning to use Spring.Net for my IoC needs, but this makes me feel that Windsor would be a better fit, and that is the one that I hear about most when IoC in .Net comes up. Not that Spring seems to be a bad offering, it has some NHibernate functionality of its own, but the Castle Project seems that little bit more tightly bound.

Equally I had been looking into using NAnt for builds, but MSBuild seems to be a perfectly good product that will be installed on any machine that I am developing on and will also be on colleagues machines so I'm not going to cause problems if I use it. The fact that NAnt needs to call MSBuild to get anything done is another point in MSBuild's favour.

This has led me to decide that as I don't have any current requirements to work in Java, I would be better off trying to learn about what seem to be considered to be the best tools for .Net when there is a clear winner, the tools that seem to work best together when there are obvious synergies, and pay attention to what seems to best fit my requirements, or has a good learning curve and plenty of documentation. If I ever need to switch to Java I can learn to use whatever tools I need to then, and if I am already familiar with IoC, TDD, ORMs etc. then picking up a new one shouldn't be too hard as the underlying skills will be similar.

The tools that I am currently looking at are:

  • MSBuild - For automated builds that can fire off unit tests and other fancy things on a regular basis.
  • NHibernate - Deals with the CRUD in my database.
  • NUnit / xUnit / MbUnit - For unit testing to make sure that I've not just gone and broken something with a minor change that I was sure had no chance of causing a problem. NUnit is the daddy, but the others seem to have their followings too, so I am open to checking them out. MSTest seems to be less well thought of right now but this may start to change come VS2010 so I'll re-evaluate things when that surfaces.
  • Moq / Rhino Mocks - A good mock framework is essential for any serious unit testing. These 2 seems to be the best, at least in the open source arena, with Moq edging it due to reports of it being simpler to get started.
  • NCover / Partcover - for giving code coverage analysis of my unit tests. The free version of NCover is getting old now and is reportedly having some problems with some .Net 3.5 code so Partcover may end up coming to its rescue. Again this is something that may also be addressed with newer versions of studio.
  • Castle Windsor - For its Inversion of Control tools (a concept that is currently blowing my head up when I try to read about it. Methinks I'm just going to have to dive in and do some to grasp it.) There may also be other parts of the Castle Project that get a look in later on.
  • CruiseControl.Net - If I decide to set up continuous integration route then this is the tool for me, but CI may not really be applicable for a 1-man development team so it is a low priority to get sorted out.

There may well be more to add to this as I get deeper down the rabbit hole.