Sunday, 2 September 2012

Testing Framework Review: NUnit

In a previous post I reviewed MSTest. This time I will focus on NUnit. NUnit is an open-source testing framework that has been around for a long time – in fact I think there was a time when this was the only test framework for .NET - and is very mature and stable. From the NUnit website:

NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit, the current production release, version 2.6, is the seventh major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages.

Integration

NUnit is a separate project meaning that direct Visual Studio support is not provided. However Visual Studio 2012 will allow different frameworks apart from MSTest to be used as the primary unit testing framework - this includes TFS builds too.

In the meantime, the following steps are required:

Download from NuGet

NuGet provides two packages for NUnit:

The NUnit package contains the core of the framework while the NUnit.Runners contains the various test runners needed to run the test assemblies.

Adding these packages to a Visual Studio project is very simple as NuGet will automatically download the latest versions and insert the correct project references required.

One initial gotcha though is that all the test runners by default assume the .NET 2.0 CLR is the correct runtime environment to use, so if you are using the .NET 4 CLR you will have to update all the *.config files to use the correct framework version; simply a matter of commenting out one line in each *.config file, though there are several to modify.

Project Items and Snippets

Unlike MSTest which provides project items and snippets with the IDE, NUnit does not provide any by default. However these items are not difficult to create yourself if required.

Standalone

Although some initial setup is required one possible benefit is that NUnit is a standalone framework - it can be run anywhere without requiring installation, simply by copying the correct files.

Team Build

TFS 2012 will be able to use the same Unit Test plugin model that Visual Studio 2012 uses meaning in future it will be a lot easier to integrate NUnit into the Team Build process.

Until then though it is possible to use NUnit within Team Build but only via a custom build activity and translating the NUnit XML output into MSTest results. This webpage explains how it is possible to do it, though the process looks quite longwinded to me.

Writing Tests

Tests are written like this in NUnit:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using NUnit.Framework;
   6:  
   7: namespace SampleCode.NUnit
   8: {
   9:     // Denotes a Test Class for NUnit to find
  10:     [TestFixture]
  11:     public class CalculatorTests
  12:     {
  13:         // Denotes a Test Method for NUnit to run        
  14:         [Test]
  15:         public void Add_AddOneAndTwo_ReturnsThree()
  16:         {
  17:             var result = Calculator.Add(1, 2);
  18:  
  19:             // Assertions can be written with a fluent API to make them more descriptive
  20:             Assert.That(result, Is.EqualTo(3));
  21:         }
  22:  
  23:     }
  24: }

There are a much wider variety of assertions provided by NUnit compared to MSTest. There is also a fluent/constraint API provided which allows a more descriptive style of writing if you find that useful.


Data Driven Tests


NUnit supports data-driven tests by writing parameterised test methods and decorating them with special attributes like so:



   1: [Test]
   2: [TestCase(1, 2, 3)]
   3: [TestCase(5, 10, 15)]
   4: [TestCase(30, 2, 32)]
   5: public void Add_AddDataValues_ReturnsExpectedResult(int first, int second, int expected)
   6: {
   7:     var actualResult = Calculator.Add(first, second);
   8:  
   9:     Assert.That(actualResult, Is.EqualTo(expected));
  10: }

Unlike MSTest, NUnit sees this as three separate tests and will display it as such in the test runners.


It is also possible to write a data-driven test by defining a data source using the [TestCaseSource] attribute which defines a property/method which returns an enumerable collection of object values to pass in as parameters.

The only thing that NUnit does not provide out-of-the-box is the ability to store data values and load from a file/external source, only code values can be used. However, using the [TestCaseSource] attribute utility methods can be created by yourself to do that.


Running Tests


Until Visual Studio 2012 comes out NUnit tests cannot be run directly via the IDE but there are a number of other options available.


The console runner is the most basic test runner available and works from the command line.


NUnitConsole


The GUI runner is a standalone application with it's own user interface. Tests are represented in a tree view along with their results and any failures are reported on the right-hand side. Notice also that data-driven tests are split further down into more tests to run.


NUnitGUI


A nice feature of the GUI runner is that it is able to detect changes in the test assembly when it is rebuilt. When a change is detected, the GUI runner can be configured to reload the assembly and automatically run the last set of tests to allow for a continuous testing strategy.


It is also possible to run NUnit via an MSBuild task, e.g. as an after-build step. This is done by simply executing the console runner using the <Exec> task, similar to this:



   1: <Target Name="AfterBuild">
   2:     <Exec Command="..\packages\NUnit.Runners.2.6.1\tools\nunit-console.exe $(TargetPath)" />
   3: </Target>

Build output then appears as follows:

------ Build started: Project: SampleCode, Configuration: Debug Any CPU ------
SampleCode -> C:\Experiments\UnitTestAnalysis\SampleCode\bin\Debug\SampleCode.dll
------ Build started: Project: SampleCode.NUnit, Configuration: Debug Any CPU ------
SampleCode.NUnit -> C:\Experiments\UnitTestAnalysis\SampleCode.NUnit\bin\Debug\SampleCode.NUnit.dll
NUnit-Console version 2.6.1.12217
Copyright (C) 2002-2012 Charlie Poole.
Copyright (C) 2002-2004 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov.
Copyright (C) 2000-2002 Philip Craig.
All Rights Reserved.

Runtime Environment -
OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
CLR Version: 4.0.30319.269 ( Net 4.0 )

ProcessModel: Default DomainUsage: Single
Execution Runtime: net-4.0
....
Tests run: 4, Errors: 0, Failures: 0, Inconclusive: 0, Time: 0.103 seconds
Not run: 0, Invalid: 0, Ignored: 0, Skipped: 0

========== Build: 2 succeeded or up-to-date, 0 failed, 0 skipped ==========


Performance


Performance of running tests seems to be faster than MSTest, even with a significant number of tests to execute.


Reports


Apart from the output represented by various test runners, an XML report can be produced by either the console or GUI runner. Once in an XML format, this can then be transformed into another format, e.g. a HTML file to make it human readable or a *.trx (MSTest) output file so that Visual Studio can understand it.

Unfortunately no sample XSL stylesheets are provided as standard by the NUnit package so this work has to be carried out by yourself or by searching on the Internet for a suitable one.


Extensibility


There are some extensibility points within NUnit but a lot of the most common features are provided as standard so there is very little else to require from it.


My Opinion


In my opinion NUnit is a lot better than MSTest. NUnit is very stable, fast, well supported and documented and supports many of the use case scenarios that you would typically use day to day. Although MSTest beats it in terms of IDE integration even without the new Unit Test Adapter it is still very easy to setup and use; the fact that the GUI runner automatically reloads assembly changes means you can have an almost-continuous test setup.


And for a while I was perfectly happy with using NUnit, until I found out about xUnit.net


More next time!

Wednesday, 29 August 2012

Time for a Change

When I first started this blog I wasn’t sure how long it would last, so I made some initial decisions such as picking a free blogging platform as my host. As a result I may have gone a bit overboard with the design of it; it is hard to know what your blog looks like when there is no content on it to give you an idea. Because of this I felt that the look of this blog was too dark and too “busy”.

Taking a leaf out of Microsoft’s newfound focus on it’s Metro/Modern/Whatever-you-call-it UI style, I thought I would make the design simpler and focus on making it more readable and just focus on the content, now that I actually have some.

This is also the first time I’m writing a post in something other than Blogger’s online editing tools. They were fairly good but there were just too many annoyances I found, such as filling in hyperlinks would send me right back to the top of the page, and formatting (especially code snippets) was a real pain. This post was written in Windows Live Writer which I am very impressed with so far.

So just a quick update this time, normal service will resume shortly.

Sunday, 26 August 2012

Testing Framework Review: MSTest

Recently I wrote about what I learned from Test Driven Development (TDD) and for the most part glossed over the issue of which testing framework to use. In that post I said that I didn't like MSTest and ended up preferring xUnit.net, but was I too quick to judge? Was that a snap decision? Had I really investigated all the features of each framework?

As I am the sole TDD knowledge base at work currently I was also asked to write up an objective analysis of each the major frameworks that I was considering. I therefore thought this would be a good opportunity to share my findings to the world in case anyone else found them useful.

So I shall write three new posts giving my full review of the following .NET test frameworks I looked at and tried out: MSTest, NUnit and xUnit.net. I'm sure there are others out there but these were the ones I kept seeing through internet research on a regular basis. I shall try and present the facts as best I can but you will also see my opinions sprinkled throughout.

This first post will be focused on...

MSTest

MSTest is the testing framework from Microsoft and is built into some previous versions Visual Studio but is included as standard with Visual Studio 2010, which is the version I will be referring to from here on out. You can see the reference documentation here.

Integration

Because MSTest is built into Visual Studio itself, integration between Visual Studio and MSTest is very tight. Straight from the IDE you can:
  • Create a test project
  • Create a test class
  • Use code snippets provided to define a test method
  • Run tests using commands/shortcuts and view the results in an IDE tool window
  • View report/result files.
Also, TFS 2010 has the option built-in to run MSTest assemblies as part of a Team Build process and it understands the MSTest result file format so it can be included in the build output.

A possible downside of deep integration though is that MSTest cannot run standalone without Visual Studio installed, unlike other frameworks. For instance, if a Continuous Integration (CI) build server were set up you would have to install the entire IDE just to use MSTest. It is possible to just find the necessary assemblies required for MSTest to force it to be standalone, as this blog post describes, but you would also have to fiddle around with the registry to include certain references which could be more painful than it is worth.

Writing Tests

So what do unit tests look like with MSTest? Here is a simple example:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace SampleCode.MSTest
{
    // Denotes a Test Class for MSTest to look for
    [TestClass]
    public class CalculatorTests
    {        
        // Denotes a Test Method for MSTest to run
        [TestMethod]
        public void Add_AddOneAndTwo_ReturnsThree()
        {
            int first = 1;
            int second = 2;

            var result = Calculator.Add(first, second);

            // MSTest assertion
            Assert.AreEqual(3, result);
        }        
    }
}

MSTest provides several assertion methods via the Assert class, though it does not seem as feature complete as other frameworks.

Methods provided are:
  • AreEqual
  • AreNotEqual
  • AreSame
  • IsInstanceOfType
  • IsNotInstanceOfType
  • IsNull
  • IsNotNull
  • IsTrue
  • IsFalse
There are also specialised StringAssert and CollectionAssert APIs.

Exception assertions must be done using the [ExpectedException] attribute. Other frameworks have moved on from this approach, making MSTest a bit antiquated in this area. Below is an example of how to test that something has thrown an exception:

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ExceptionTest()
{
    TestMethod(null);
}

It is possible to make your own assertions but you will have to define your own Assert class to provide additional assertions. For example, this blog post explains how to define an Assert.Throws() method to replace the clunky syntax for exception checking shown above for a more functional, fluid approach.

Data Driven Tests

Originally I thought that MSTest was not able to use data driven tests - that is tests which require input from an external source - but I was wrong. MSTest does support data driven tests but not in the same way as most other frameworks.

Below is an example of such a test:

[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\Add_DataDrivenTestCases.csv", "Add_DataDrivenTestCases#csv", DataAccessMethod.Sequential)] 
[DeploymentItem("SampleCode.MSTest\\Add_DataDrivenTestCases.csv")]
public void Add_DataDriven_ReturnsCorrectResult()
{
    var first = Convert.ToInt32(TestContext.DataRow["First"]);
    var second = Convert.ToInt32(TestContext.DataRow["Second"]);
    var expectedResult = Convert.ToInt32(TestContext.DataRow["Result"]);

    var actualResult = Calculator.Add(first, second);

    Assert.AreEqual(expectedResult, actualResult);
}

Note the following:

  1. MSTest does not support parameters in test methods like other frameworks do.
  2. A [DataSource] attribute is used to define where the input data comes from. This example uses a CSV file but XML and databases are supported too.
  3. Because parameters are not supported, all data input has to be extracted from a TestContext class (which you have to define yourself). Getting each column of the file actually returns an object, meaning you have to do yet more work to convert values into something meaningful.
In comparison to other frameworks (which I will highlight in future posts) this feature feels incredibly clunky to me. I used Visual Studio's IDE tools to auto-generate this test method for me as I doubt I would remember the syntax for it each time. It should also be noted that you cannot have inline data - that is data defined as constants such as what NUnit supports.

Running Tests

Running tests in MSTest is incredibly easy. Simply right-click in a test code file and click "Run Tests" for the Test Window to appear, such as below:



From this window you can view detailed results of each test.

For a data-driven test, only one row appears in this window yet it is run multiple times for each row in the data source, which can appear confusing. Viewing the detailed results of a data-driven test will show the individual results though.

It is also possible to run MSTest via an MSBuild task, e.g. as an after-build step. This is done by simply executing the MSTest console application using the <Exec> task like this:

<Target Name="AfterBuild">
    <Exec Command='"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\mstest.exe" /testcontainer:"$(TargetPath)"' />
</Target>

Build output then appears as follows:

------ Build started: Project: SampleCode.MSTest, Configuration: Debug Any CPU ------
  SampleCode.MSTest -> C:\Experiments\UnitTestAnalysis\SampleCode.MSTest\bin\Debug\SampleCode.MSTest.dll
  Microsoft (R) Test Execution Command Line Tool Version 10.0.30319.1
  Copyright (c) Microsoft Corporation. All rights reserved.

  Loading C:\Experiments\UnitTestAnalysis\SampleCode.MSTest\bin\Debug\SampleCode.MSTest.dll...
  Starting execution...

  Results               Top Level Tests
  -------               ---------------
  Passed                SampleCode.MSTest.CalculatorTests.Add_AddOneAndTwo_ReturnsThree
  Passed                SampleCode.MSTest.CalculatorTests.Add_DataDriven_ReturnsCorrectResult
  2/2 test(s) Passed

  Results               Add_DataDriven_ReturnsCorrectResult
  -------               -----------------------------------
  Passed                SampleCode.MSTest.CalculatorTests.Add_DataDriven_ReturnsCorrectResult
  Passed                SampleCode.MSTest.CalculatorTests.Add_DataDriven_ReturnsCorrectResult
  Passed                SampleCode.MSTest.CalculatorTests.Add_DataDriven_ReturnsCorrectResult
  3/3 test(s) Passed

  Summary
  -------
  Test Run Completed.
    Passed  5
    ---------
    Total   5
  Results file:  C:\Experiments\UnitTestAnalysis\SampleCode.MSTest\TestResults\petermonks_ACHILLES 2012-08-14 10_42_21.trx
  Test Settings: Default Test Settings
========== Build: 2 succeeded or up-to-date, 0 failed, 0 skipped ==========

Performance

Performance of running tests seems a little slower than other frameworks as MSTest saves all results to file meaning IO time is consumed a lot. This didn't cause any problems with my simple test suite but this might be significant if hundreds of tests are being run at once.

Extensibility

Since .NET 4 and Visual Studio 2010, MSTest has been able to be extended to some degree although doing so is hard work. For example, this blog post explains how to extend MSTest to use inline data-driven tests that have parameters, such as:

[TestMethod]
[Row(1, 2, 3)]
[Row(4, 5, 6)]
public void ParameterTest(int x, int y, int z)
{
    // Test code here...
}

However from this post it looks incredibly long-winded to implement and setup, whereas other frameworks have this ability as a built-in feature.

My Opinion

So these are the facts I researched, what do I think about MSTest now?

Overall I am still of the opinion that I was right to not use it. Having tried other frameworks, which I will give my review on in future posts, I can see that MSTest is clunky to use and not as fully featured as other frameworks. The only Unique Selling Point I can see with it is that it is built into Visual Studio so it is easy to get started with it and integrate it with other Microsoft tools, something we do require at work as we want to use TFS Build to get test results. But seeing as Visual Studio 2012 is going to include the new Unit Test Adapters to allow other test frameworks to be used instead, even this is starting to become a moot point. 

I've also noticed that some open-source Mircosoft projects don't even use MSTest and use something else. Maybe it is because they are trying to keep everything self-contained in these projects, but I read it as not even some developers in Mircosoft would consider using their own test framework.

So MSTest isn't for me. Next time I shall review NUnit.


Thursday, 16 August 2012

Visual Studio 2012: What's Your Problem?

Today I read that Visual Studio 2012 has finally been released (to MSDN subscribers at least). There are a lot of new features I'm looking forward to using in my work, some of which are highlighted in these videos. And yet instead of people being excited about it, all I see in blog comments are people still complaining about this:

Too little colour, TOO MUCH SCREAMING!!
Image courtesy of Scott Hanselman (http://www.hanselman.com/blog/content/binary/Windows-Live-Writer/Visual-Studio-2012-RC-is-released---The-_AA5F/Visual%20Studio%20Light%20Theme_2.png)

Seriously, are we still complaining about this?

I have to admit that when I first saw screenshots of the new interface I also thought "what have they done?" This was back when everything was grey and dull. I initially didn't like the UI but rather than just complain endlessly about it I thought I would wait until I could at least try it myself and not judge it on a few screenshots of a beta product. I even gave what I hoped was constructive criticism about it , like many others did. And eventually Microsoft got the hint and made changes and toned down the extreme parts of the new UI and now I feel more comfortable with it.

But this UI change has ended up masking any number of new features and improvements that actually make you productive to the point that people can only focus on one thing: they hate how it looks.

Now I'm not saying that it is perfect or anything, or that it ever could be, but I personally am happy enough with the final result and want to focus on what it can do rather than how it looks. Yet when I see comments like this still I wonder what people are really focusing on:

Dear Microsoft,
I've been a fan and supporter for 20+ years.  This time you guys outdid yourselves (yes, I am being sarcastic).
WHAT IN THE WORLD WERE YOU GUYS SMOKING WHEN YOU CAME UP WITH THE BRILLIANT IDEA OF GETTING RID OF THE COLORS???
I CAN'T WORK LIKE THIS.  I VERY QUICKLY UNINSTALLED IT AND WILL NOT ALLOW ANY DEVELOPER ON MY TEAM TO USE THIS.  OUR PRODUCTIVITY WOULD FALL BY AT LEAST 30% IF WE STICK TO THIS IDE.
JUST IN CASE YOU ARE WONDERING WHY I'M TYPING EVERYTHING IN UPPER CASE, IS BECAUSE I'M TRYING TO GIVE YOU A TASTE OF YOUR OWN MEDICINE!!!!!
It's not even constructive, this is just a person ranting to the world because they can. Unfortunately a lot of people follow this tack so it just feels like I'm drowning in negativity.

I try very hard to not be critical of things and if I have to complain I try very hard to at least give suggestions to improve something, but it seems the age of the Internet and social media simply makes us into people who want to argue for arguments sake and that disappoints me.

And I want Microsoft to know that I at least am looking forward to using VS2012.

Friday, 10 August 2012

What I've Learned About Test Driven Development

At the end of April this year me and my colleagues prepared and deployed a big website/system update. A lot of things would change and get better and despite our rather lax testing procedures - testing being not very formal and done by us developers - we felt we had tested it as much as we possibly could and were very happy with what we did. We deployed it over a weekend with scheduled downtime, did our updates along with some server enhancements, and brought the site back up...

...Starting on the following Monday and continuing for the next two weeks we did nothing but patch holes with endless hotfixes and grovel to our customers promising that we will fix all the bugs they were reporting non-stop as soon as possible. One of our web services did not start up again for an entire weekend and our biggest client wanted to know why they couldn't access our systems. Users were complaining that the website kept kicking them out at random times which we eventually found out was being caused by a StackOverflow exception occurring every 30 minutes and crashing the IIS web process. It got to the point where the CEO got involved and at the eventual end of this nightmare my manager had to go and visit some key clients to personally assure them that all was well and this would never happen again.

We felt gutted. By our standards this was the most tested release we had ever done and yet it ended up being the worst one in our company's history.

This is all background to the real purpose of this post. When the dust settled we all sat down and discussed what went wrong and why and one of the key points we learned (though not the only one) was that our testing strategy was dire. In the absence of a real software tester (though we have one now) it was down to the people writing the code to do testing, and it tended to be a quick couple of run-throughs in certain areas to make sure things worked as we expected. This was not good enough and I simply felt that I couldn't trust our own system anymore.

A friend of mine talked to me about the benefits of Test Driven Development (TDD) a couple of weeks earlier and at this point I put it towards my team. I felt that, as well as having a proper software tester, we as developers needed to think about testing from the very start. In essence, we had to build quality into our code.

And so began my long journey into a development practice that I had never tried before and yet now I feel makes so much sense to me. Last week marked the very first unit and functional tests ever entered into our codebase and although they only cover a tiny fraction of our entire code I feel much more comfortable that that code works as it should, even before it goes to our tester to evaluate.

I will not go into the entire TDD process - there are enough resources on this already - but I thought as this was a learning process for me I would share with you what I've learned in the past few months.

Roy Osherove to the Rescue!

I did a lot of research into TDD, trawling the internet and reading through a book a colleague lent me but I still had many questions and things I was not sure about. What is the difference between a unit test and an integration test? What if your code has to read from a database or a file? What is a stub and what is a mock?

Then I listened to this Hanselminutes podcast of Scott Hanselman talking to Roy Osherove, author of The Art of Unit Testing, and all my questions were answered in 30 minutes. If anyone else is having trouble understanding unit testing and TDD I would very much recommend listening to this as it helped me a lot.

No-One Likes MSTest

Before you can write your tests though you need a unit testing framework to help you write your them, but which one do you choose?

Initially I started using MSTest as that came integrated with Visual Studio and I could experiment quickly with learning the TDD process, but in the end I saw some flaws with it - as do many others

  1. The benefit of having MSTest integral to Visual Studio can also be it's downfall as you simply cannot run it standalone.
  2. MSTest simply provided the bare minimum of features to make it worthy of calling it a unit testing framework. I learned that other unit testing frameworks were more capable and had far better features than MSTest, including assertion of exceptions and data-driven tests.
  3. The last problem I had was more of a personal one in that the test runner window didn't seem to make it that clear to me that all the tests had passed or failed. Compare the screenshots below of the MSTest and the NUnit test runner:
An example of the MSTest runner. Notice that tiny little tick at the top of the window? That tells me that all the tests passed.

Courtesy of Robust Haven ( http://www.robusthaven.com/blog/linux-development/Unit-test-runner-in-bash-for-C-and-CPP-libraries)
Now compare that to the NUnit test runner. See that great big green line? Guess what that means?

Courtesy of litemedia ( http://litemedia.info/data-driven-test-cases-in-nunit)


So I tried out NUnit which I liked very much and seemed very dependable, and most recently xUnit.net which I finally settled on.

What I learned from this though is that, once you take MSTest out of the equation, any test framework is usually good enough and it simply comes down to personal preference. I went with xUnit.net because it provided several things I found useful straight out-of-the-box such as an MSBuild task to add to your project builds - if a test fails then the build fails - and it provides a XML stylesheet by default to create HTML reports rather than having to make one myself, a la NUnit.

Doing it Backwards

The very first stumbling block was that I had to mentally switch around my working style to effectively be back to front. Write tests before code? How was that meant to work, surely you need something there to try out? But as long as you follow the Red, Green, Refactor process it does actually work.

Even so, for a beginner like me it required a very large mental shift. For my very first unit test I must have sat there for a good half-hour thinking "How do I write this test? Where do I start?" Once you get past the first test - usually making sure something works - then the next test seems a bit more obvious: "What if I pass in the wrong input?" This could produce quite a few more unit tests so now the ball starts rolling. And once the first code function is tested you start to see a pattern so the next batch of tests seem a bit easier to write, and so on.

As long as you can start writing some unit tests to begin with, the process becomes a lot more intuitive up to the point where it seems like second nature and the way you were working before seems so arcane now.

Designing Your API

The other thing that struck me is that, despite the word "test" in Test Driven Development, initially it feels more like I'm writing a very detailed specification for all my objects. As I am building up each test it feels like I am defining what the code should be doing which to my mind is almost like a list of requirements - function A will allow a string to be passed in, but not an empty string or one that has more than 100 characters etc.

TDD has also made me think a lot more about object dependencies and code design. When I sat down and looked at my codebase as it stands now, many objects in the business logic layer call straight into the data-access layer and database to do something and these objects simply assume that that will just work - there has to be a database present to do anything in my system. For the real world that makes perfect sense as a system without a database is pretty much useless, but in a testing scenario it cannot be assumed that a database is there and for unit testing nothing should be touching external state.

This led me to wonder how I could actually test anything if all of my code is so inter-dependent on each other (or tightly coupled). The answer for TDD is to make your code loosely coupled instead which impacts your code design and makes you think a lot more about patterns and practices like Dependency Injection. As a result I'm starting to feel a lot happier with the overall design of my code as it has started to resemble smaller, Lego-sized blocks which can be combined together into bigger systems.

Start From Scratch

Following on from the previous section if you already have a large codebase and start to introduce TDD into it, like me you might find it a bit daunting. Where do you start? Do you retroactively add unit tests into existing code? And what about dependency problems you have?

So I learned that the best way to learn about TDD and introduce it into your working practices is to start on something brand new, a clean slate. That way you can build up your tests and knowledge as you go. And if you can't start from the very beginning? Then pick a new feature that you're due to develop and start thinking about how you would implement it in a TDD fashion. If only one part of your codebase has been written with testability in mind then that is better than nothing.

Test As Much As You Can

My final thought is that initially I thought that you would have to aim for 100% test coverage to make you feel that you had done a good job. While it is a target to aim for, you don't have to achieve it, or maybe it is just impossible to reach that goal for many reasons.

The very first feature I implemented into our product that was written with TDD in mind only has about 30 unit tests and that doesn't even cover the entire feature end-to-end, the reason being that existing code has dependencies that I cannot extricate just yet. But the new code I have written, that was unit tested. In all, the total test coverage is a tiny percentage but at least I can build upon it over time.

All in all I now think in a TDD style and find it difficult when I have to revert back to the old-fashioned cod-then-test mentality. It's only been a few months since I started investigating this process as a possibility but I'm glad that I did as I feel one step closer to being a better programmer.

Wednesday, 1 August 2012

Becoming a Father: One Year On - Part 3


This is the third part of my retrospective on my first year as a new father. To view all the parts, please click on one of the links below:

Part 1 - The Beginning
Part 2 - The First Two Weeks
Part 4 - The Accident

This post focuses on...

Getting the Hang of Things

Once I became more accustomed to waking up several times in the night followed by waking up early in the morning to go to work each day, I came to realise that things do tend to settle into a routine (almost). My wife and I learned many things about our son in the first 6 months:

  1. He liked to be on the go all the time, he simply did not like sitting still much. This resulted in me usually having to administer some kind of silly walk whilst carrying him so he felt the exaggerated movement and which kept him happy. Although after 30 seconds of this around the living room my leg muscles would be screaming at me to stop.
  2. He also didn't think much of napping during the day. Whilst other parents might boast that their little angel would have a 1 - 2 hour nap in the afternoon, we were forced to endure almost a whole day of feeling exhausted and looking after him since he would sleep for at most 30 minutes at a time (with usually a 4 - 5 hour gap inbetween).
  3. The flip-side of not napping during the day though was that he at least seemed to understand the day-night cycle and would sleep longer and better during the night. My wife and I started off going to bed at around 8pm for at least 3 months because we simply couldn't stay awake any longer!
  4. He was heavy and I was weak. When he was born he weighed 8lb 11oz - which for those not in the know is fairly large - and he pretty much worked his way up to the 91st percentile of his baby contemporaries and was generally the largest of all his baby friends. I am not a physically strong person and having to carry him around started to get very draining, though I eventually got more used to it - perhaps it could have been considered as weight training for me!
  5. My wife tried feeding him expressed milk as breastfeeding did not go well but eventually he started to drink more and more formula milk to the point where he could, after a few months, drink almost an entire bottle of it every 3 hours. That could explain the weight gain...
  6. He got to a point 3 months in where he slept pretty much through the night - the holy grail of parenting! But then, at 4 months, he switched things around a bit and did the dreaded sleep regression. Why babies apparently do this I do not know. I was having dinner with some friends and boasting about how he slept through the night now at such a young age when I got a text message from my wife telling me that he started waking up at night; that was the night when he started waking up several times a night for the next few months. I resolved from then on to never discuss his sleeping habits with anyone other than my wife lest I somehow jinx everything.
  7. Most importantly though was that we could start to see that he had a personality. It is hard to describe in writing but there were little things he did that you could just tell were a part of him.

The Daily Routine

I found it incredibly helpful that a daily routine seemed to materialise over time - I am a programmer after all! My wife and I both agreed that I would do the (very) early morning feed as once I'm awake I tend to stay awake; I'm a very light sleeper. 

Once that was done and everyone was still asleep I could get to my morning chores which started about 6am. These involved having a shower and breakfast for me of course but also cleaning up all the milk bottles, getting the bottle steriliser ready and boiling water for his formula milk for the day. If I had time I'd also prepare his reusable nappies after they had been washed and dried. 

At about 7:30am I would go wake up my wife so she could have a shower before I went to work and I would look after the boy in the meantime. We decided that my wife would get as much rest as possible and not the other way around since she would be the one spending all day with him on the go - remember, he didn't like napping. She basically needed as much rest as possible whereas, despite me having to do a full day's work too, at least I would be sitting down for most of it and downing cups of tea through the day.

Once I got home from work I would take over from my wife and give him his bath and get him ready for bed. In the first month that tended to be quite late as he was still getting used to a regular bedtime so that meant I had to learn how to hold him in one arm whilst I ate my dinner with the other. Eventually though I was responsible for putting him to bed by giving him his bedtime bottle, burping him and letting him fall asleep on my shoulder before putting him in his moses basket.

Here's a little secret I'll let you in on: whilst letting him fall asleep on me I spent many a night playing through Angry Birds on my phone. I actually got quite far through the game in this fashion!

"What dear? No, I'm putting our son to bed, what did you think I was doing?"
Image courtesy of Echo Enduring Blog ( http://blog.echoenduring.com/2010/11/23/learning-about-design-from-angry-birds/)

It Does Get Better

My last post may have left you thinking that raising a child is a hellish experience, and initially it is incredibly demanding. It still is but as 6 months roll on you realise that you can deal with things better now, that he also grows up more and changes with you and somehow you both meet in the middle to end up having fun together.

He seems a lot happier now :)

Monday, 16 July 2012

Is It Really That Complicated?

I've recently been reading Fabien Sanglard's blog, particularly his fascinating code reviews on the Doom and Quake source engines. Apart from making me feel a bit stupid not understanding how BSP trees work, something else strikes me regarding my own work:

What I do isn't really that complicated.

At the heart of my job I write code to make a website work, and if I consider the bare essential tasks that it needs to do I think I'd have the following shortlist:
  1. Get data from a database
  2. Do something to the data
  3. Put that data into a webpage and send back to the client
  4. Profit
By now it's safe to assume we've figured out how to do all of these steps easily - except perhaps the last one! There are a ton of ways to read and write to a database from code, either using ADO.NET or a variety of ORM frameworks, just as many ways to visualise that data (WebForms, MVC, Silverlight etc), and the only real work you should do in theory is the logic that sits between those parts.

Yet if this is all I need to do, why does it still seem so complicated to get anything done? Why does it still take me ages to implement a new feature when "code-reuse" should be helping me? I mean, it's not like I'm writing a game engine with crazy 3D maths and physics to calculate in nanoseconds, attempting to cure cancer or even writing software for spacecraft. Apart from some technical challenges that do exist, I think it mainly boils down to two things.

Other People

Your customers usually don't tend to think in the same way as you do. They might say "hey, can you add in the ability to search our website like Google? In fact, can we not just use The Google on our database or something? And possibly email all the search results to us? It can't take that long, right?" I like to try and keep things as simple and generic as possible, yet find that when "other people" get involved it tends to spiral out of control.

Take, for example, the financial sub-system I inherited from my predecessor. At work we have a system which calculates how many units each of our clients uses based on what assessments have been completed and how many reports have been generated. These units are then used by account managers to translate into real money to calculate invoices, such as 1 unit = £10 for instance.

So this sounds simple, right? Surely it's just adding up numbers and computers love adding up numbers. Did I mention though that if component A was generated before component B then you only add units for B, but if C and B are combined into one then we halve the units of A. Oh, I forgot, if D is generated between B and A then we add C and E together but only cap to a maximum of 6 (which can be changed based on which country you are in) and then if you bring F into the mix... and this kind of logic goes on and on in an endless spiral of doom.

Why does the system work this way? Because that is how other people decided it should work, because apparently business rules should never be simple. It also didn't help that this evolved, as most products do, into a big mess which means that business rules end up circling around each other without you even being fully aware of it.

When I first started this job I had to spend 3 months understanding all the many intricacies of this system because only my predecessor knew how it truly worked - despite being told by the managers what they wanted. It has now gotten to the point where only I know how every item is charged for and even the management have to double check with me.

And to be fair, there is one other thing that tends to complicate matters just as much as other people...

Myself

I tend to get very attached to the code I write. In an ideal world I feel as though my source code should be beautiful to gaze upon, to be able to admire it's sheer simplicity whilst also marvelling at how it can handle so many complex tasks at once. Sometimes I look back on code I wrote maybe a month or two ago, which at the time I was perfectly happy with, yet now I feel it is ugly and horrible and what was I thinking? This simply has to go because now I know exactly how it should be written...

But this is the real world and experience has taught me that sometimes I have to just "get it done" no matter how it ends up. And if we're being honest who else apart from me really cares about what my code looks like? The other day I decided to bash-out three quick features for my website as I felt that customers really needed them; I created them as quickly as possible (since I do have other projects to complete) so the code wasn't pretty, sometimes even copied-and-pasted with some changes. I look back on it now and I don't like how it looks. Yet my customers won't care, because what they see are three new features that make their life easier and they work, which at the end of the day is the most important thing in your product.

Keep It Simple, Stupid

Simplicity is what I strive for in life. I genuinely feel that the simplest solution is always the best as there are fewer complications to consider and less chance of anything going wrong, and I really try to impress that upon people. Yet at the end of the day outside factors have a way of creeping in and adding complications to your best laid plans, and I've built up enough work experience to realise that although the simplest solution may be the best, it's not necessarily what people want.