MSBuild: Unit Tests (6 of 7)
November 30th, 2006
Unit testing has caught as a part of the agile methodologies the past several years. It acts as a second line of defense against problems in a deployed environment with the first line being a successful compilation. For a few years now .NET developers have used NUnit to produce unit tests. It is a clone of the JUnit framework which was created for Java development.
Alongside your projects you can place a set of classes which carry specially marked classes and methods and validate that the compiled code conforms to the project requirements. In doing so, you can have the automated build ensure that a new enhancement or bug fix does not cause an unwanted side effect which breaks compliance. And these tests should be run early and often. The sooner you can discover an error the easier it will be to identify the change which caused it. The use of unit tests speed up the development process and also allow the development team to confidently make changes which may otherwise be considered too risky.
There has been an ongoing debate over when tests should be created and how many tests should be put in place. There is also discussion on whether private methods should be tested in addition to public methods. I simply focus on testing the integration points within my applications, such as whenever the web application makes calls to a remote system like a web service or the database. Generally the bugs I see come from those integration points so I do my best to prevent bugs from sneaking in that way. And as I collect bug reports I can identify areas which could use more unit tests to cut down on future issues.
Checking the unit tests after the build and before any packaging and deployment will prevent bad code from being deployed. The image to the right shows what it looks like for a test to fail. The successful tests show up in light gray while the failures show up in red which are very easy to identify at a glance. When tests fail you can optional abort the remaining tasks in the MSBuild script which is what was done here.
Below is the MSBuild script with the RunTests target used to run these tests.
These tests are held in a class library project called UnitTests. In the above RunTests target you can see that it simply references the UnitTests.dll assembly. The NUnit framework uses reflection and the TestFixture and Tests attributes to pull out and run the code to be tested. By doing so the build process does not need to be adjusted as tests are added and removed from this class library.
Prior to checking in any new code, developers could run these tests using this script to ensure they did not break anything. Many teams make it a rule that no code that does not compile or pass all tests can be checked into source control. It is a good policy to follow. And once these tests are run by the build server there should be no problems, but occasionally there is the occasional issue. But at least you can identify the cause and developer responsible right away so it can be changed easily. Imagine the alternative. You may not know that a change had an unwanted side effect for weeks, and by that time you may not know where to look to make the correction.
More Information:
Next in this series, packaging.

March 8th, 2007 at 9:07 am
Could youl please shed more light on the example above. I realized that you use MSBuild.Comunity.Tasks.dll and I see you omitted
some code for brevity ...
I am a newbie and need working example if any.
As of now I am getting MSB4057 the target Build does not exist in the project.
Then I imported Microsoft.CSharp.targets which then lead to some new errors of type 'No input specified.'
Thanks
Adia