比Java平台下的麻烦太多。光是一个Unit Test就折腾了很长时间,很多都推荐NUnit,但是用Visual Studio还得让大家都安装NUnit,也为了看看完全用微软的方案是否可行。
由于我们现在的持续集成的工具选的是TeamCity,所以主的build脚本只能基于NAnt,因为TeamCity虽然支持MSBuild或者VS,但是没有对应的Runner或者兼容的Agent,所以基本上等于不支持。
从NAnt里面调用VisualStudio的工程文件编译是没有问题,因为有nantcontrib,但是运行Unit Test就成问题了,google了很长时间也没有找到好的解决方案,有人自己写了dll去掉整个solution的unit test(微软的msunit),还有个Gallio项目,都不怎么好用,最后回到起点:使用命令行的方式,但是需要在TeamCity的机器上安装Visual Studio,还好我们是大企业版,随便装。
最后出来的build.xml:

<?xml version="1.0"?>
<project name="POC" default="build" basedir=".">
    <property name="nantcontribdll" value="c:/nantcontrib-0.85/bin/NAnt.Contrib.Tasks.dll"/>
    <property name="mstestcommand" value="C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\MSTest.exe"/>
    <property name="unittestdir" value="unittest"/>
    <property name="outputtype" value="debug"/>
   
    <target name="build" description="compiles the source code">
        <loadtasks assembly="${nantcontribdll}" />

        <msbuild project="MyProject\MyProject.csproj">
                <property name="teamcity_dotnet_use_msbuild_v35" value="true"/>
        </msbuild>
        <msbuild project="MyProjectTest\MyProjectTest.csproj">
                <property name="teamcity_dotnet_use_msbuild_v35" value="true"/>
        </msbuild>
    </target>
   
    <target name="unittest" description="Run unit test" depends="build">
        <delete dir="${unittestdir}" />
        <mkdir dir="${unittestdir}" />
       
        <exec program ="${mstestcommand}" commandline="/testcontainer:MyProjectTest\bin\${outputtype}\MyProjectTest.dll /resultsfile:${unittestdir}\MyProjectTest.trx" basedir="MyProjectTest"/>
    </target>
   
    <target name="clean" description="Clean output">
        <loadtasks assembly="${nantcontribdll}" />
        <delete dir="${unittestdir}" />
        <msbuild project="MyProject\MyProject.csproj" target="clean">
                <property name="teamcity_dotnet_use_msbuild_v35" value="true"/>
        </msbuild>
        <msbuild project="MyProjectTest\MyProjectTest.csproj" target="clean">
                <property name="teamcity_dotnet_use_msbuild_v35" value="true"/>
        </msbuild>
    </target>
</project>

对于NAnt需要特别说明的是:在TeamCity里面可以用NAnt0.85版本,但是本地调用的话必须用NAnt0.86beta1(当前最新版本),只有这个版本支持.net3.5,而TeamCity使用自己的方式支持.net3.5,就是我们看到的丑陋的teamcity_dotnet_use_msbuild_v35,不能定义一个全局的property了事,必须在每个msbuild任务里面定义这个property。