Posts Tagged NUnit

Setting up Continuous Integration with Cruise Control.Net

I recently set up Cruise Control on Vista PC for development purposes and I thought it might be useful to document the process I followed.

If you don’t know what Continuous integration is then I recommend a that you read a brief overview of it by Cruise Control .Net developers

In my implementation there are 3 components to continuous integration system.

Source control (I am using VisualSVN)
Complier (MSBuild.exe, which is part of the .Net Framework)
Nunit, a unit test runner

The process involved is fairly straightforward. First the trunk of the source code is pulled from the repository to the working directory. MSbuild.exe compiles the source code, then the nUnit tests. Finally the tests are run against the complied code. The success or failure of of the tests is output as an xml file and is reported in web dashboard.

I have also installed CCtray, a program that runs in the systray showing the state of the last build. It allows builds to be run manually, as opposed to a on a timed interval . The CC web dashboard shows a wealth of information on the build state and if any Nunit tests have failed.

I achieved this by following instructions on The CCNET homepage which I’ve summarised below.

In my case the editing, building and testing of the code is done on my local machine along with hosting the source control. In a bigger environment your would host these services seperately for performance reasons, but in my scenario this is not an issue.

Having installed from the download page I installed setup.exe. The CCTray.exe will be installed once the server has been setup

Once CC net is installed the server must be started by running the CruiseControl.net icon on the desktop.

To test if the install was successfully, I pointed my browser to http://localhost/ccnet/ViewFarmReport.aspx

The first hiccup I encountered was a an IIS 7 error:
HTTP Error 500.23 – Internal Server Error
An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode.

Which was easily solved after a quick google, I found that the solution was to switch the application to a Classic mode application
pool

The server is controlled via it’s config file, which is found in C:\Program Files\CruiseControl.NET\server\ccnet.config. This file is at the heart if to the entire integration process, and contains the list of actions the server will complete on each build.

Any edits to ccnet.confg will restart the CCnet server.

To complete the first stage of a build, which is to checkout the latest version of the code, I added the source control block to ccnet.config. It which defines where code is within the repository and where it is checked out to. My example is for a SVN but Cruise Control.net supports many other source control systems.

<sourcecontrol type="svn">
  <trunkUrl>http://localhost:8080/svn/myproject/trunk</trunkUrl>
  <workingDirectory>c:\dev\ccnet</workingDirectory>
  <executable>c:\Program Files\VisualSVN Server\bin\svn.exe</executable>
  <username>username</username>
  <password>password</password>
</sourcecontrol>

The next step is to add to the config file instructions to build the code that has been checked out.

To do this I used the MSbuild.exe file found in C:\Windows\Microsoft.NET\Framework\v3.5. To save my aching fingers from typing too much, I added the above path to it to the system path.

Within the tags I inserted the block as below

 <msbuild>
          <executable>
            C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe
          </executable>
          <workingDirectory>c:\dev\ccnet\trunk</workingDirectory>
          <projectFile>project.sln</projectFile>
          <buildArgs>
              /noconsolelogger /p:Configuration=Debug /v:diag
           </buildArgs>
          <targets>Build</targets>
          <timeout>0</timeout>
          <logger>
           c:\Program Files\
       CruiseControl.NET\server ThoughtWorks.CruiseControl.MsBuild.dll
           </logger>
</msbuild>

This builds the code that has been checked out. Note that the workingDirectory values are the same.

I also added another block which complies the nUnit tests. In my case, the trunk directory that was checked out contains both the data classes and Nunit test classes so only one checkout was required.

Now that the code has been complied, the unit tests are to be run. I have added the path to the nunit exes to the system path. The Nunit-console.exe runs the tests and creates an xml file containing the status report of the tests run against the classes.

I added the exec block inside the tags

       <exec>
          <executable>nunit-console.exe</executable>
          <baseDirectory>
              C:\Program Files\NUnit 2.5.2\bin\net-2.0
          </baseDirectory>
          <buildArgs>
             c:\dev\ccnet\trunk\NunitTests\bin\Debug\NunitTests.dll 
           /xml:c:\testresults\testoutput.xml
           </buildArgs>
          <buildTimeoutSeconds>10</buildTimeoutSeconds>
          <successExitCodes>0,1,3,5</successExitCodes>
       </exec>

At this point in the build process the tests have been run, so I now wanted to display the results in the CC web dashboard. To do this, I merged the testoutput.xml file into the build status output. This block needs to be put inside the block

<merge>
        <files>
            <file> c:\testresults\testoutput.xml</file>
          </files>
</merge>

Finally I activated the xmllogger, by adding to the block the

Under this configuration it was possible for me to check code into the trunk of my project, and force a build that checked out the code and unit tests, and automatically ran the tests against it, outputing the results to a the CCNet web dashboard, via a single click.

This entire process can be run from the CCNet web dashboard, or more conveniently, the CCTray sys tray program. There is a moderate overhead in setting up continuous integration but the return on investment grows the longer the system is developed.

Where to go on from here?

My setup could be improved in a number of ways.

  1. Auto build on each commit by using a post commit hook on subversion
  2. Selenium testing for the web functional tests
  3. using FxCop to analyse the complied code to find improvements and include this in build reports

Some of these topics I will explore in future posts

, ,

1 Comment

Command Pattern Tutorial: Part Two

This is part two of a tutorial to create a Home Automation Program, using the Command Pattern.  It assumes you have already read  part one

I have used NUnit to unit test my  classes,  and I have provided the test script I created in my subversion repository

Now that I have created the classes I need, I have coded an ASP.NET web project using those classes.

You can demo the Remote Control Application here (UPDATED: This is now hosted on the Azure cloud)

This version is implemented without using AJAX, and uses traditional postbacks instead. Look and feel is very basic, as an AJAX version of the site will posted in a future blog post.

The source code for this site is available

The left hand panel displays the remote control for the home automation system, and contains seven slots Command Slots. Initially there are no commands set in these slots, so the on and off buttons are disabled. To add a Command to a slot, the user may click the Edit button to select a list of available commands. Once a command is selected, it may be turned on or off by clicking the on or off button for that slot.

To the right hand of the page, the status panel displays the state of the appliances for the house, which are by default, turned off. Once an on or off button is clicked, the status of the appliances will be updated.

The list of available commands is kept in the database, when a new House object is created, it’s list of commands is retrieved and then instantiated.

The Drop Down List is populated as thus:

private void LoadCommandsDropDownMenu(House h)
{
ArrayList array = h.CommandList;
ArrayList DDarray = new ArrayList();
DDarray.Add("Select Command");
foreach (House.command_pair cmds in array)
{
DDarray.Add(cmds.Name.ToString());
}
DDCommandList.DataSource = DDarray;
DDCommandList.DataBind();
}

If we update the Command Objects table in the database we can add new commands. We can even update the list of valid commands without changing existing code. By using the pattern we can change the commands of each command slot at runtime.

My next post will show how to use implement some nice AJAX features using JQuery.

,

2 Comments