Build modules - csUnit integration with Hudson continuous build

I've just come from reading my favourite blog - Jeff Atwood's Coding Horror, which touched on the purposes of build scripts.

It goes without saying how important build scripts & automated builds are for projects of any significant size or scale. The ability to seperate out the function of creating a build not only makes it a foolproof process to grab the latest & greatest version off the build server, but can also deliver you far greater capabilities of creating archives of versions & patches. If you're struggling to manage your builds, where past versions are often strewn across a wide array of folders, perhaps it's time you did yourself the justice of installing an automated build service.

It's a funny situation though. When starting off, the obvious choice seems to be VSS source control with Cruise Control handling your builds. Firstly, VSS was discontinued over 5 years ago. Sure it still ships with VS, but why would you go through the punishment of using it? How many times a day do you say to your colleagues 'Hey buddy, can you check in Program.cs?' There are so many other better (and free) source control applications out there that will increase your productivity, and generally make your life at work far more enjoyable. No more waiting on people to check stuff in just so you can change a connection string in your web.config!

Two of the better source control systems out there are SubVersion & Mecurial. At the end of the day & after a lot of research from my colleague, it turned out that Mecurial has a few more features; and although you need to do a bit of research on how to use it, it's well worth it. It supports branching (eg: you get to a point in your project where you want to split the application into a Linux & Win version), patches (eg: need to disable functionality in a couple of files for your demo users), and the nice thing too is that it forces you to label all your updates - no more laziness!

On the automated build side of things, Hudson works brilliantly. Unlike cruise control, you don't need to master how to create the fussy XML build scripts as it's all interface driven. It has heaps of other neat features such as full Ajax console output (so you can see the build output as it progresses in your browser), it's controllable through msbuild, and the nice part is that thanks to its highly pluggable structure, it fully integrates with mecurial!

Among the many other merits of the system, it provides plugins for things like fxCop, with graphs so you can see how your violations are travelling over time & builds. The other thing too is that it supports nunit scripts. The downside is that a while back I made a conscious decision to switch to csUnit, as I liked the idea of having test blocks that can put in my code which accept parameters through attributes thusly:

[Test]

[csUnit.Experimental.DataRow(530, 530)]

[csUnit.Experimental.DataRow(620, 530)]

[csUnit.Experimental.DataRow(530, 620)]

[csUnit.Experimental.DataRow(530, 620)]

[csUnit.Experimental.DataRow(600, 600)]

[csUnit.Experimental.DataRow(530, 600)]

[csUnit.Experimental.DataRow(530, -1, ExpectedException=typeof(System.Security.SecurityException))]

public void GetUser(int callingUserID, int requestedUserID)

{

That's all great but it doesn't really jive when it comes to Hudson. Solution? Well it turns out that the nunit plugin simply uses an XSLT to transform its XML output to look like a junit output. So it's really a simple case of just creating an XSLT that converts the csUnit XML output to do the same thing, which gives you an XSLT that looks like this:

<?xml version="1.0" encoding="utf-8"?>

<!--

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    Name: csunit-to-junit.xsl

    Author: Andrew den Hertog

    Date: 18 October 2007

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    Transforms csUnit xml result files to a junit compatible xml file for

    the purposes of integration with Hudson continuous build.

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

-->

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" />

 

<xsl:template match="/test-results">

    <testsuites>

 

        <xsl:for-each select="assembly">

            <xsl:variable name="assembly" select="substring-before(@name, ',')" />

 

            <testsuite

                name="{$assembly}"

                tests="{count(test)}"

                time="{sum(test//@duration)}"

                failures="{count(test[@test-result='error'])}"

                errors="{count(test[@test-result='error'])}">

 

                <xsl:for-each select="test">

                    <testcase

                        classname="{$assembly}"

                        name="{substring-after(@name, concat($assembly,'.'))}"

                        time="{@duration}">

 

                        <xsl:if test="@test-result = 'error'">

                            <failure>

                                MESSAGE:

                                <xsl:value-of select="@reason"/>

                            </failure>

                        </xsl:if>

 

                    </testcase>

                </xsl:for-each>

            </testsuite>

        </xsl:for-each>

    </testsuites>

</xsl:template>

 

</xsl:stylesheet>

It's then just a matter of swapping XSLT's in the nunit pluggin (or creating a new plugin for csUnit). I love simple solutions, almost as much as I love not having to worry about source control or maintaining my own set of builds.

posted @ Friday, November 02, 2007 8:20 AM

Print

Comments on this entry:

No comments posted yet.

Your comment:



 (will not be displayed)


 
 
 
Please add 7 and 4 and type the answer here:
 

Live Comment Preview:

 
«November»
SunMonTueWedThuFriSat
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456