Part 3: The Epiphany
In the last part of this series I covered my first foray into trying to improve code quality through the use of FxCop and StyleCop. It was just a small area of the overall development process to tackle and it had mixed success. My team wasn’t really happy as we had set out to improve things but ended up introducing another hurdle on the road to the fundamental objective to deliver software, on time, without drama, to satisfied clients.
So why the change?
The software we were creating and maintaining was built using ASP.Net 2.0 and were initially quite successful, but the resulting applications generally had business logic woven throughout the web application and in the code-behind files. There was considerable time and effort required for testing (usually manually debugging line by line and random screen clicking) and time spent bug fixing was seriously hampering progress and seeing release date after release date pass by. We also quickly realised that rolling out updates to the software was often a complex and fraught process which further sapped time away from getting on with what we should have been doing, delivering value in the form of new features and adapting to changing business requirements.
Not a happy recipe for maintainable and robust code. The domain models were either anaemic or non existent with complex business logic woven throughout application layers (which had become symbolic rather than a means to achieve a separation of concerns) and after a few releases the code had morphed into an unholy a spaghetti mess. This was not the development utopia I had envisioned… so I went back to the drawing board at the start of the next project. I started hunting around for a better way to get a clean separation of concerns to stop the code-behind mess and improve quality by reducing bugs. I found what I was looking for in the first few ASP.Net MVC previews, it promoted separation of concerns and was much easier to create unit tests. While I was learning about Asp.Net MVC, I watched Rob Conery’s excellent series of webcasts on StoreFront for building an ecommerce site on MVC, and as an added bonus it contained a few other revelations which would eventually lead to my epiphany. Thanks Rob! I’ll come back to MVC in the next part of the series but for now, onwards with the quest for Code Quality.
One of the tools Rob used and raved about in his storefront series was a code refactoring tool called ReSharper so I went off to get an evaluation copy and see what the fuss was about. About an hour later I couldn’t imagine how I hadn’t heard of it let alone ever done without it. Even now, several years later, the prospect of having to use Visual Studio without a refactoring tool is bleak, even with the improved features of 2010. If you’ve never heard of ReSharper, CodeRush, JustCode or any of the other refactoring tools for Visual Studio check them out, you might also become addicted…
ReSharper like most of these kind of tools has a plugin model and the one I was especially interested in was *StyleCopForResharper. The plugin could pick up our StyleCop settings and provide UI hints from with Visual Studio. Along with a host of other inspection options to help improve our code quality we could now easily comply with all of the StyleCop settings our SVN pre-commit hook demanded. *StyleCopForReSharper has since been integrated directly into the StyleCop so this has been depreciated on codeplex.
Overall the team was much happier complying with the rules as it was now pretty painless to do so as we developed our code, we had achieved our goal of complying with all these rules without creating an onerous process. Over time our code became much more consistent in layout and style and coding habits formed across the team. All this fuss over some coding conventions may seem trivial, you might be thinking, but I believe it makes a huge difference in reviewing and understanding codebases when it has a consistent layout and style, and much more importantly, the team agreed.
There were still some grumbles among the team though which came from the upgrades and rule changes, so over time they would modify their settings, deliberate or otherwise, which would flare up commit issues and some frustration, so once again I started my research, the process still had some work to do which we will revisit later but for now we will leave this topic and move on to the next.
Enter an agile practice
I sort of stumbled across our continuous integration server by accident whilst trying to improve our StyleCop and FxCop process with ReSharper. The same company JetBrains also have a continuous integration server called TeamCity. Being the curious sort I downloaded a copy and began to poke and prod it. Never having used Visual Studio’s Team Foundation Server product (which was ridiculously priced at the time), I was oblivious to what these things were for so the concept was completely new to me but my epiphany was looming.
Around this time I was also researching how we could solve the many problems that we faced daily whilst developing our software, combining this with the concept of continuous integration and improved testing I went to amazon in search of knowledge. I think it was reading the following two books that really shaped my plan of how to approach these problems and which ultimately started me down the road toward the agile principle and practices that we use today. Better late to the party than never but continuous integration and test driven development was my epiphany and it didn’t just open the door in terms of ideas, it blew them off with dynamite!
|Test Driven Development (The Addison-Wesley Signature Series) Kent Beck|| |
The excellent Kent Beck book was my first real introduction to test driven development (TDD), test doubles (stubs, mocks, fakes) and a few other things besides, a real eye opener. It gave me a proper grounding in the basics I was looking for and plenty of new concepts and ideas which I began to learn more about and it’s coming up next in the series. The continuous integration book also contained a wealth of practical information about how I could move more towards the development utopia I wanted in some practical ways (I’m not there yet and probably never will be but it will always remain an ambition). Now I’m a proponent of the theory that a little knowledge can be a dangerous thing, so I wouldn’t recommend just reading these books and decide that it’s enough, I highlight these books in particular as the starting point that helped me formulate a lot of questions which subsequently led me to read a whole bunch more of the Addison-Wesley series, Kent Beck series, Bob Martin, and various others, on a range of Agile, Testing, Patterns and Design topics. It was a rather large influx of information at the time and my head was spinning but rather than rush out and try everything at once, I took some time (many months actually) to digest the various sources of information, getting some context and seeking out differing viewpoints until I felt I could make some informed choices, and more importantly reason them out by selling the merits of them to the team. On the whole they were supportive and enthusiastic about making some changes and without this, it probably wouldn’t have worked. It is with the continuous integration server TeamCity that I decided I would tackle first as I now believe it is the single most important concept you can introduce to improve a team. IMHO it underpins everything else.
Continuous Integration - The backbone
I downloaded the free edition of TeamCity and began to learn more about it. I also had a look at some alternatives (Hudson/Jenkins and CruiseControl) but I chose to use TeamCity and I’m still very happy with it several versions later.
One of the biggest drawbacks I found to setting up a CI server to fully realise it’s potential is the amount of time and effort it can take to get it right, especially as you move towards continuous deployment as we eventually did. I started off very simply to try and get used to using TeamCity. First I installed it on our development server and set up a single build agent. With that task completed I poked about the application trying to understand all the bits. I decided that to start with I would use their Visual Studio Solution build runner. It allowed me to quickly point to the solution in our Subversion repository and have it build whenever code was committed to the subversion repository by using a trigger in TeamCity configuration. As usual, I wish I had found the great guide on DimeCasts which walks you through setting up TeamCity before I had started, but it’s pretty user friendly as it is to get the basics up and running. On the surface, such a simple setup doesn’t really give you anything more than building a solution in Visual Studio on your desktop. The value of this approach really comes into it’s own once you progress beyond the starting point and start adding additional processes to the build which will be covered later in the series.
The summary bit
So far all I’d read a lot but not really done much other than put in place some tools and policies to regulate code styling and layout. The major ‘aha’ moment for me though was the concept of continuous integration as a way to formalise and regulate the complex process of delivering software and use test driven development to address the fragile and buggy nature of our code on which we lost so much time.
At the same time as setting up our CI server, we were starting an ASP.Net MVC project (in beta 1 at the time, circa 2008) and it was the team’s first venture into test driven development which is what’s up next.
|<< Part 2 – Time to change||Part 4 – Code Quality: Testing >>|