views:

242

answers:

2

After looking around I can't find a simple answer to this problem.

I am trying to create an MSBuild file to allow me to easily use SpecFlow and NUnit within Visual Studio 2010 express.

The file below is not complete this is just a proof of concept and it needs to be made more generic.

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;

    <PropertyGroup>
        <BuildDependsOn>
            BuildSolution;          
            SpecFlow;
            BuildProject;           
            NUnit;
        </BuildDependsOn>
    </PropertyGroup>

    <PropertyGroup>
        <Solution>C:\Users\Craig\Documents\My Dropbox\Cells\Cells.sln</Solution>
        <CSProject>C:\Users\Craig\Documents\My Dropbox\Cells\Configuration\Configuration.csproj</CSProject>
        <DLL>C:\Users\Craig\Documents\My Dropbox\Cells\Configuration\bin\Debug\Configuration.dll</DLL>
        <CSFile>C:\Users\Craig\Documents\My Dropbox\Cells\Configuration\SpecFlowFeature1.feature.cs</CSFile>
    </PropertyGroup>

    <Target Name="Build" DependsOnTargets="$(BuildDependsOn)">
        <Message Text="Build Started" Importance="high" />
        <Message Text="Build Ended" Importance="high" />
    </Target>

    <Target Name="BuildSolution">
        <Message Text="BuildSolution Started" Importance="high" />
            <MSBuild Projects="$(Solution)" Properties="Configuration=Debug" />
        <Message Text="BuildSolution Ended" Importance="high" />
    </Target>

    <Target Name="SpecFlow">
        <Message Text="SpecFlow Started" Importance="high" />
            <Exec Command='SpecFlow generateall "$(CSProject)"' />
        <Message Text="SpecFlow Ended" Importance="high" />
    </Target>

    <Target Name="BuildProject">
        <Message Text="BuildProject Started" Importance="high" />
            <MSBuild Projects="$(CSProject)" Properties="Configuration=Debug" />
        <Message Text="BuildProject Ended" Importance="high" />
    </Target>

    <Target Name="NUnit">
        <Message Text="NUnit Started" Importance="high" />
            <Exec Command='NUnit /run "$(DLL)"' />
        <Message Text="NUnit Ended" Importance="high" />
    </Target>
</Project>

The SpecFlow Task looks in the .csproj file and creates a SpecFlowFeature1.feature.cs. I need to include this file when building the .csproj so that NUnit can use it.

I know I could modify (either directly or on a copy) the .csproj file to include the generated file but I'd prefer to avoid this.

My question is: Is there a way to use the MSBuild Task to build the project file and tell it to include an additional file to include in the build?

Thank you.

A: 

I couldn't think of any way to achieve without any modification to the .csproj file.

The approach I'd suggest would look like this.

In your .csproj you Import a container target file

...
<Import Project="SpecFlow.target" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
...

just above the CSharp.targets.

Specflow.targets would look like this

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
    <ItemGroup>
        <Compile Include="@(Compile)" />
    </ItemGroup>
</Project>

so it doesn't harm while building the project from VS.

You could then use the Output of your SpecFlow Exec and add it to the SpecFlow.targets file

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
    <ItemGroup>
        <Compile Include="@(Compile)" />
        <Compile Include="SpecFlowFeature1.feature.cs" />
    </ItemGroup>
</Project>

...

and clean SpecFlow.targets after building your .csproj.

Filburt
+2  A: 

I found no way of doing it without editing the project file.

So I made an MSBuild file to:

  • Copy the project files
  • Run the copies through SpecFlow
  • Add the new .cs files to the copied projects
  • Compile the projects
  • Debug Run each of the compiled DLLs through NUnit
  • Clean up - Delete the copied projects

I've blogged about how to use it here:

http://learntdd.wordpress.com/2010/06/10/using-specflow-and-nunit-on-visual-studio-2010-express/

(It's version 1, I'd like to improve the script)

Craig Norton
I read your blog post and followed all the steps, but it doesn't work for me. As an example I used the Tekpub MVC starter site and it doesn't work. The error I get is this: "C:\WebTest\VS2010ExpressSpecFlow.xml" (default target) (1) ->(AddSpecFlowCSFilesToProject target) -> C:\WebTest\VS2010ExpressSpecFlow.xml(86,5): error : Object reference not set to an instance of an object.
WVDominick
+1 for taking the time to do this.
WVDominick
Thank you for having a go, having people hit it is what I needed. I'll have a look at this as soon as I have time...probably this weekend.
Craig Norton
As an initial guess though I would say that the build script expects to find .feature files as Content (Property->Build Action->Content)
Craig Norton
Great article! We will definite link it from the SpecFlow site.
Gaspar Nagy