About Me

Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

Automating Your Builds With NAnt - Part 5

Archive

Blogroll

 Agile Developer Venkat's Blog
 Ayende @ Blog
 B#
 Barry Gervin's Software Architecture Perspectives
 Boy Meets World
 Brad Abrams
 Canadian Developers
 Christopher Steen
 Claritude Software News
 Clemens Vasters: Enterprise Development and Alien Abductions
 Coding Horror
 Coding in an Igloo
 Dare Obasanjo aka Carnage4Life
 Darrell Norton's Blog [MVP]
 David Hayden [MVP C#]
 Don Box's Spoutlet
 Eric Gunnerson's C# Compendium
 EZWeb guy: Jeffrey Palermo [C# MVP]
 Fear and Loathing
 Generalities & Details: Adventures in the High-tech Underbelly
 Greg Young [MVP]
 Greg's Cool [Insert Clever Name] of the Day
 IanG on Tap
 Ingo Rammer's Weblog
 ISerializable - Roy Osherove's Blog
 James Kovacs' Weblog
 Jason Haley
 Jean-Luc David
 Jeremy D. Miller -- The Shade Tree Developer
 JetBrains .NET Tools Blog
 Jimmy Nilsson's weblog
 John Bristowe's Weblog
 John Papa [MVP C#]
 Jon Skeet's Coding Blog
 JonGalloway.ToString()
 Jump the Fence or Walk Around
 Lambda the Ultimate - Programming Languages Weblog
 Larkware News
 Lutz Roeder
 Marquee de Sells: Chris's insight outlet
 Martin Fowler's Bliki
 Mike Nichols - SonOfNun Technology
 MSDN Magazine - .NET Matters
 MSDN Magazine - All Articles
 OdeToCode Blogs
 Onion Blog
 Planet TW
 Raymond Lewallen [MVP]
 Rockford Lhotka
 RodMan's Corner
 Roger Johansson's blog
 Sahil Malik - blah.winsmarts.com
 Sam Gentile's Blog
 Scott Bellware [MVP]
 Scott Hanselman's Computer Zen
 ScottGu's Blog
 secretGeek
 Service Station, by Aaron Skonnard
 Signum sine tinnitu--by Guy Kawasaki
 Stephen Toub
 Steve Eichert's Blog
 Steven Rockarts
 The Blog Ride
 The Coding Hillbilly
 The Daily WTF
 TheServerSide.net: News
 Tim Gifford
 Vance Morrison's Weblog
 you've been HAACKED

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 519
This Year: 28
This Month: 0
This Week: 0
Comments: 1593

 Monday, April 17, 2006
Monday, April 17, 2006 4:09:57 PM (Mountain Standard Time, UTC-07:00) ( Tools )

I left off talking about building and compiling the NUnit tests for the application. Of course, what good are tests if you can’t run them and see results! Time to shift our attention toward running the tests in an automated fashion so that we can get feedback on the health of the application. All of the tests that are currently in the application were written with the aid of the great NUnit testing framework. Typically I utilize the NAnt exec task to shell out to the NUnit console application to run all of the tests defined in an assembly. I prefer this to the actual nunit task and its variants as my build file is not affected in any way when I upgrade to a newer version of NUnit. Last time we left off with 2 compiled assemblies in the build directory. One assembly for the code to be tested, and one assembly for the tests themselves.

BuildDirectoryPreTest It’s time to add a new target to the build file that will allow for execution of the tests:

<target name="test" depends=”test.compile”>
</target>

Notice that by again taking advantage of the “depends” attribute, we can ensure that the tests have been compiled prior to test execution.The first thing you need to see is if there are any objects that you are going to be testing that require a dependency on a .config file. If they do then you first need to copy the web/app.config into a file that NUnit can work with. It is always the same file name format “[ProjectName].Test.[OutputExtension].Config”. In our scenario, because the project name is DotNetRocks, the config file would get copied to the file :

DotNetRocks.Test.dll.config

To keep everything in one place (highly recommended) I am going to copy the config file (using the new name) to the build directory. To accomplish this I can make use of the copy task.

<target name="test" depends=”test.compile”>
    <copy file="config\Web.Config" tofile="build\${nant.project.name}.Test.dll.config" />

</target>

Of course, you would change the location as necessary to pull the Web.Config file from wherever it may reside in your directory structure (typically with the web/win project itself). With the config file taken care of, I now need to copy to the build directory any libraries that will need to be in the build directory for the tests to work. In this particular scenario I need to copy the NUnit and NMock2 libraries into the build directory. Once again, I can take advantage of the copy task to accomplish this:

<target name="test" depends=”test.compile”>
       <copy file="config\Web.Config" tofile="build\${nant.project.name}.Test.dll.config" />
        <copy todir="build" flatten="true">
            <fileset basedir="tools">
                <include name="**\NMock2.dll" />
            </fileset>
        </copy>
         <copy todir="build" flatten="true">
            <fileset basedir="tools\nunit\bin">
                <include name="*.dll" />
            </fileset>
        </copy>
              
    </target>

As you can see, because the tests make use of both the NUnit and NMock2 frameworks, I need to copy all of the relevant dll’s from those frameworks into the build directory before the tests can run. NUnit is an interesting one, because sometimes you can get away (by sheer fluke) with this step and NAnt will fallback to using the NUnit version that is installed in the GAC (if you installed NUnit on your machine). This is problematic though. If you upgrade the version of NUnit in your tools directory and build your tests against that version of NUnit, you will only be able to run the tests using the GAC version if it matches the one in your tool directory. If the versions are different, you will get an error when you try to run your test. Again, getting back to the principle of  “keeping everything you need to run the project in one place” it is best to avoid reliance on the GAC for NUnit and the like. This is why all of the necessary dlls from both frameworks are being copied into build directory. If I were to stop there, the build directory would look like this after running the test target:

BuildDirectoryPreTest2

As you can see all of the files we actually are responsible for generating/maintaining are at the top of the directory (notice the config file with the correct NUnit naming convention), all of the other 22 dlls (that list could be streamlined by changing the filter for the fileset) are purely there for running the tests.

With the supporting files all in place it is time to run the tests. To accomplish this, it is time to use a new task. The exec task. Again, I am not going to go into all of the details, attributes etc for the exec task, as the NAnt docs do a good job of that. I’m going to focus on using it to run NUnit. I’ll need to update my test target:

<target name="test" depends="test.compile">
  <copy file="config\Web.Config" tofile="build\${nant.project.name}.Test.dll.config" />       
       
        <copy todir="build" flatten="true">
            <fileset basedir="tools">
                <include name="**\NMock2.dll" />
            </fileset>
        </copy>
       
        <copy todir="build" flatten="true">
            <fileset basedir="tools\nunit\bin">
                <include name="*.dll" />
            </fileset>
        </copy>
                                      
        <exec basedir="tools\nunit\bin"
              useruntimeengine="true"
              workingdir="build"
              program="nunit-console.exe"
              commandline="${nant.project.name}.Test.dll /xml=${nant.project.name}.Test-Result.xml" />
           
       
    </target>

Pay attention to 2 of the key attributes : basedir and workingdir. basedir is the directory that the program I want to execute is in. workingdir is the directory in which the program will execute (hence the need to copy all required dlls,config files etc to the build directory). The program attribute is self explanatory, and finally the commandline attribute is the argument string to invoke the program with. Notice I am telling nunit to execute against the test library I have place in the build directory (DotNetRocks.Test.dll), and I want the results of the tests to be placed in a file named DotNetRocks.Test-Result.xml (this file will be placed in the build directory). If I run my test target now I will get the high level results output to the console, consoleoutputas well as a xml file containing detailed tests results placed in the build directorytestresults. As a quick heads up for things to come, I will talk about how you can integrate the results that are spit out by the NUnit console into a continuous build engine (CC.Net), for analyzation and integration of the results into the build process.

 

Hopefully this will get you started on the way to integrating automated tests into your build infrastructure. Next up, let’s bring the DB into the picture!






TODO