Generate Tests From MsBuild

General

To generate your code-behind files at compile time, simply add the SpecFlow.Tools.MsBuild.Generation nuget package to your project.

You will need VS2017/MSBuild 15 to use this packages.

Removing the custom tool and include the generated files (optional)

When adding a feature file, Visual Studio automatically enters "SpecFlowSingleFileGenerator" as the Custom Tool in the file's properties. This ensures that the class files are re-generated whenever the feature file is saved. You can remove the custom tool to prevent this from occurring, as any class files that are not up-to-date will be generated during the build process anyway:

If you remove the code generator you have to include the generated files in your project dynamically. To do so, add the following lines at the end of your project file (.csproj) in a text editor:

<Target Name="AfterUpdateFeatureFilesInProject">
    <!-- include any files that specflow generated into the compilation of the project -->
    <ItemGroup>
        <Compile Include="**\*.feature.cs" />
    </ItemGroup>
</Target>

Define Additional Options (optional)

The TechTalk.SpecFlow.targets file defines a number of default options in the following section:

<PropertyGroup>
    <ShowTrace Condition="'$(ShowTrace)'==''">false</ShowTrace>
    <OverwriteReadOnlyFiles Condition="'$(OverwriteReadOnlyFiles)'==''">false</OverwriteReadOnlyFiles>
    <ForceGeneration Condition="'$(ForceGeneration)'==''">false</ForceGeneration>
    <VerboseOutput Condition="'$(VerboseOutput)'==''">false</VerboseOutput>
</PropertyGroup>
  • ShowTrace: Set this to true to output trace information.
  • OverwriteReadOnlyFiles: Set this to true to overwrite any read-only files in the target directory. This can be useful if your feature files are read-only and part of your repository.
  • ForceGeneration: Set this to true to forces the code-behind files to be regenerated, even if the content of the feature has not changed.
  • VerboseOutput: Set to true to enable verbose output for troubleshooting.

To change these options, add the corresponding element to your project file before the <Import> element you added earlier.

Example:

<PropertyGroup>
  <ShowTrace>true</ShowTrace>
  <VerboseOutput>true</VerboseOutput>
</PropertyGroup>
...
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\SpecFlow.2.2.0\tools\TechTalk.SpecFlow.tasks"  Condition="Exists('..\packages\SpecFlow.2.2.0\tools\TechTalk.SpecFlow.tasks')" />
<Import Project="..\packages\SpecFlow.2.2.0\tools\TechTalk.SpecFlow.targets" Condition="Exists('..\packages\SpecFlow.2.2.0\tools\TechTalk.SpecFlow.targets')" />
...
</Project>

You can find an example here (project Bowling.SpecFlow)

Process the Generated Files (optional)

You can further process the generated files. The TechTalk.SpecFlow.targets file defines two targets (BeforeUpdateFeatureFilesInProject and AfterUpdateFeatureFilesInProject) that can be overridden. Furthermore it outputs the list of generated files for the MsBuild item @(SpecFlowGeneratedFiles).

The following example shows an overridden AfterUpdateFeatureFilesInProject target that moves the generated files to a separate folder:

<Target Name="AfterUpdateFeatureFilesInProject">
  <Move 
    SourceFiles="@(SpecFlowGeneratedFiles)" 
    DestinationFolder="MyGeneratedFiles" 
    OverwriteReadOnlyFiles="true" />
</Target>