A while back, I wrote a blog post, A quick introduction to Nant, which gave, well, a quick introduction to building C# libraries using NAnt.
Since then, I’ve been using NAnt to do a lot more — notably, to run unit tests and to report on test coverage (using NCover and NCoverExplorer). The usage is pretty straightforward, and I think you’ll see how each step builds on the previous step.
- To run a default build (excluding unit tests):
nant
- To build all projects and unit tests (but don’t run :
nant build-tests
- To build all projects and unit tests, and run tests using NUnit:
nant test
- To build all projects and unit tests, and run tests using NCover to generate coverage reports:
nant cover
- To build all projects and unit tests, run tests using NCover to generate coverage reports, and open those reports in NCoverExplorer:
nant coverex
The sample below is my NAnt build file. A few notes first.
- There are only two projects referenced: Project1 and Project1.Tests. Repeat the appropriate sections to build against additional projects.
- nunit-console.exe is expected to be in the system path.
- nunit-console.exe, ncover.console.exe, and ncoverexplorer.exe are expected to be in the system path. I recommend you download and install TestDriven.Net to have all of these in a convenient place.
Now, on to the build file. It should be self-explanatory, but I added some XML comments for your convenience.
< ?xml version="1.0"?> <project name="project build" default="build" basedir="."> <description>Project -- NAnt Build</description> <property name="debug" value="true" /> <property name="build.dir" value="bin" /> <echo message="debug: ${debug}" /> <echo message="build.dir: ${build.dir}" /> <target name="init" description="sets up environment for build"> <mkdir dir="${build.dir}" /> </target> <target name="clean" description="removes old files, copies new reference DLLs"> <delete dir="${build.dir}" failonerror="false" /> <delete> <fileset basedir="${build.dir}"> <include name="*.*" /> </fileset> </delete> <copy todir="${build.dir}"> <!-- I keep shared DLLs in a directory called References --> <fileset basedir="References"> <include name="*.dll" /> <include name="*.xml" /> </fileset> </copy> </target> <target name="build" description="build projects, excluding tests (default)" depends="clean,init"> <csc target="library" output="${build.dir}\Project1.dll" debug="${debug}" doc="${build.dir}\Project1.xml"> <sources basedir="Project1"> <include name="**/*.cs" /> </sources> <references basedir="${build.dir}"> <include name="System.dll" /> <!-- add additional references here --> </references> </csc> </target> <target name="build-tests" description="build all test projects" depends="build"> <csc target="library" output="${build.dir}\Project1.Tests.dll" debug="true"> <sources basedir="Project1.Tests"> <include name="**/*.cs" /> </sources> <references basedir="${build.dir}"> <include name="System.dll" /> <include name="NUnit.Framework.dll" /> <!-- add additional references here --> </references> </csc> <!-- this copies your App.config to a file that can be found by NUnit when testing --> <copy file="Project1.Tests\App.config" tofile="${build.dir}\Project1.Tests.dll.config" /> </target> <target name="test" description="builds all and runs unit tests" depends="build-tests"> <exec workingdir="${build.dir}" program="nunit-console.exe"> <arg value="Project1.Tests.dll" /> <arg value="/xml=Project1.Tests-results.xml" /> </exec> </target> <target name="cover" description="builds all and runs unit tests using NCover" depends="build-tests"> <ncover program="NCover.Console.exe" commandLineExe="nunit-console.exe" workingDirectory="${build.dir}" commandLineArgs="Project1.Tests.dll /xml=Project1.Tests-results.xml" logFile="${build.dir}\Project1.Tests-coverage.log" coverageFile="${build.dir}\Project1.Tests-coverage.xml" assemblyList="Project1.dll" /> </target> <target name="coverex" depends="cover"> <exec workingdir="${build.dir}" program="ncoverexplorer.exe"> <arg value="Project1.Tests-coverage.xml" /> </exec> </target> </project>
josh says:
This is one of the things I want to get going, but haven’t made the time to do it. IMO a good build process includes automated tests, and this is a good way to do it. nice post.
Daniel says:
Great Article, Thanks a lot!
Artel DeVries says:
I replaced the task that builds the project with this:
This automatically takes care of the references for you.