1
May 09

Integrating NCover 1.5 with Nant builds

Getting NCover to work with nant builds was more messy than I assumed. What’s more appalling about all this is that programmers new to NCover download it from the default NCover landing page, only to find that its a paid version(3)(version 1.5 is sufficient for most use cases and serves most of the purposes.)

Another concern was that most of the the ncover tutorials on the web showed how to test a single unit test assembly even though ncover comes with a nunitproject nant task to pick out multiple test files(which is the highway case).

Without much further ado, here’s what I did

Download version 1.5.8 of NCover, v 1.4 of NCover Explorer and v 1.4 of NCover Extras

NCover Extras encapsulates the functionalities provided by NCover as a set of nant tasks. This needs to be loaded.Also CoverLib.dll that comes with NCover needs to be registered.

<loadtasks assembly="${ncover.nant.task.dir}\NCoverExplorer.NAntTasks.dll"/>

<exec program="regsvr32" workingdir="${ncover.dir}" commandline="/s coverlib.dll"/>

Add these lines before the target is called.

Now for the actual task…

<target name="coverage">

  <nunitproject project="${output.dir}\tests.nunit">

    <fileset basedir="${output.dir}">

        <include name="*.*Test*.dll" />

      </fileset>

  </nunitproject>

  <ncover

    program="${ncover.dir}NCover.Console.exe"

    commandLineExe="${nunitconsoleexe.dir}nunit-console-x86.exe"

    logLevel="Verbose"

    commandLineArgs="${output.dir}\tests.nunit /nodots /nologo"

    verbose="true"

    logFile="${coverage.reports.dir}/coverage.log"

    workingDirectory="${output.dir}"

    coverageFile="${coverage.reports.dir}\Unit.Test.Coverage.xml">

    <assemblies basedir="${output.dir}">

      <include name="CompanyName*.dll" />

      <exclude name="*.*Test*.dll" />

    </assemblies>

  </ncover>

  <ncoverexplorer

    program="${ncoverexplorer.dir}\NCoverExplorer.Console.exe"

    projectName="ProjectName"

    reportType="ModuleClassFunctionSummary"

    outputDir="${coverage.reports.dir}"

    xmlReportName="TestCoverage.xml"

    sort="FunctionCoverageDescending"

    htmlReportName="TestCoverage.html"

    showExcluded="True"

    minimumCoverage="80"

    satisfactoryCoverage="80" >

    <fileset>

      <include name="${coverage.reports.dir}\Unit.Test.Coverage.xml" />

    </fileset>

    <exclusions>

      <exclusion type="Assembly" pattern="*.Tests" />

      <exclusion type="Namespace" pattern="*.Tests*" />

    </exclusions>

  </ncoverexplorer>

</target>

The node with the nunitproject picks all the test dll’s from the output directory and builds a tests.nunit project file. This will be the input to Nunit which NCover will profile.

Digging into the NCover node you’ll see how NCover is being instructed to take pick the assemblies. If you are copying the code verbatim then change the assemblies node to pick your project dll’s and avoid test dll’s(By convention test assemblies are named ProjectName.Tests.dll). The output of this profiling task will be an xml file(Unit.Test.Coverage.xml in this case) which will be the input to NCoverExplorer, to get those fancy html outputs.

Here’s a typical NCover output xml..

image thumb Integrating NCover 1.5 with Nant builds

The next node ncoverexplorer takes the xml files and builds a html output. Something similar to what’s shown below. Additionally the attribute failMinimum(not shown in this case) will fail the build if coverage doesn’t meet the coverage percentage specified.

Here’s a sample output.

image thumb 3 Integrating NCover 1.5 with Nant builds

One little quirk I encountered here was using nunit-console.exe instead of nunit-console-x86.exe. My 64 bit Server 2008 build machine rejected the first executable outright since it ran as 64 bit.

What pissed me of in this exercise was the time it took to integrate a seemingly simple open source project. Pretty much the same experience I had dealing with DD-WRT firmware sources. Once the author/company decides to to release a higher version of the project as a paid version or to make money out of the project, they then obfuscate source paths or put in obstacles that deter consumers from downloading those open source versions.

In case of the DD-WRT the source was hidden inside GB’s of data and in this case the official NCover website removed all the forums and added nag screens asking users to signup(given below) before downloading..

image 4 Integrating NCover 1.5 with Nant builds

 Integrating NCover 1.5 with Nant builds

12
Oct 08

Targeted Ad’s

Google sure knows the guys who read Slashdot!

Slashdotad1 thumb Targeted Ad’s

100x20 digg button Targeted Ad’s

18
Aug 08

Migrating to WordPress

You can’t expect me to write blogengine plugins for Disqus, super cache, cl forms, Akismet etc. Its way too much work from my focus area. 202px Paris servers DSC00190 Migrating to WordPress

Being a lot of guys who understand technology terms like scripting and html I chose to do a source control install rather than those “one click installs”. Primary reason for this is that WordPress comes with a lot of security issues(they being the most popular) and upgrading through svn is a breeze.

Here’s how I did it.

Choose a good hosting provider. Mine’s DreamHost. They will give you ssh access apart from the usual ftp and cpanel stuff.

Create a folder in your root to host your blog (use software like putty to get into your remote hosting machine).

Assuming that your hosting provider has svn installed (which most of them do), run svn co http://svn.automattic.com/wordpress/tags/2.6.1 . (last dot included). Then go through the standard installation procedures.

Next time you need to upgrade do a svn up (as always backup everything) and you are done.

Update: This post has some missing sentences at the top. 

100x20 digg button Migrating to WordPress

17
Aug 08

Buildings

2769510069 29e4d7037e m Buildings


buildings

Originally uploaded by alainlm

A picture like this can take you a long way..


6
Jul 08

Enum with attributes

Recently I came across an implementation where enum is converted to string and vice versa (http://blogs.msdn.com/tims/archive/2004/04/02/106310.aspx ). The disadvantage here is that, say you want get the string for something like this “Not available”.

enum Status {
  Not_Available, 
  Available_For_Game, 
  Available_For_Discussion
}

The string conversion here for the first one would yield Not_Available. This is not desirable in some cases where you don’t want the “_”. A better implementation would be to create attributes to this enum and then extract this.

 
  public enum Status {
    [Status(Description = "Not Available")]      
    Not_Available = 1,      
    [Status(Description = "Available For Game")] 
    Available_For_Game = 2,      
    [Status(Description = "Available For Discussion")] 
    Available_For_Discussion = 3,
  }
  public class StatusEnumInfo {
    private static StatusAttribute[] edesc; 
    public static String GetDescription(object e)
    {
      System.Reflection.FieldInfo f = e.GetType().GetField(e.ToString()); 
      StatusEnumInfo.edesc = f.GetCustomAttributes(typeof(StatusAttribute), false) as StatusAttribute[]; 
      if (StatusEnumInfo.edesc != null && StatusEnumInfo.edesc.Length == 1)         
        return StatusEnumInfo.edesc[0].Description; 
      else         
        return String.Empty;
    } 
    public static object GetEnumFromDesc(Type t, string desc)
    {
      Array x = Enum.GetValues(t); 
      foreach (object o in x) {
        if (GetDescription(o).Equals(desc)) {
          return o;
        }
      } return String.Empty;
    }
  }
  public class StatusAttribute : Attribute {
    public String Description { get; set; }
  }
 
  public class Implemenation {
    public void Run()
    {
      Status statusEnum = (Status)StatusEnumInfo.GetEnumFromDesc(typeof(Status), "Not Available"); 
      String statusString = StatusEnumInfo.GetDescription(Status.Available_For_Discussion);
    }
  }

You are of course free to generalize this. Correct me if this is not a correct implementation.

Technorati Tags: ,
100x20 digg button Enum with attributes