Updating Plugins for SpecFlow 3

This article covers updating existing plugins to work with SpecFlow 3. If you are interested in developing your own plugins, the documentation for SpecFlow plugins is here. This documentation includes links to sample plugins that you can use as a basis for developing your own.

Overview

With SpecFlow 3, the plugins you want to use are no longer configured in your app.config file. To use existing plugins with SpecFlow 3, the easiest way is to package your plugin as a NuGet package and edit the .targets and .props files as described below. These files need to have the same name as your NuGet package.

As part of the configuration of your plugin, you also need to determine which plugin assembly to load based on whether you are using Full Framework or .NET Core.

Generator Plugins

To update your generator plugin:

  1. Package your plugin as a NuGet package if you haven’t already.
  2. The actual DLL to reference is determined in the .targets file. You need to load a different version of the plugin depending on which version of MSBuild you are using (Full Framework vs .NET Core). Using the xUnit .targets file as an example (the file is here):
    <PropertyGroup> 
       <_SpecFlow_xUnitGeneratorPlugin Condition=" '$(MSBuildRuntimeType)' == 'Core'" >netstandard2.0</_SpecFlow_xUnitGeneratorPlugin> 
       <_SpecFlow_xUnitGeneratorPlugin Condition=" '$(MSBuildRuntimeType)' != 'Core'" >net471</_SpecFlow_xUnitGeneratorPlugin> 
       <_SpecFlow_xUnitGeneratorPluginPath>$(MSBuildThisFileDirectory)\$(_SpecFlow_xUnitGeneratorPlugin)\TechTalk.SpecFlow.xUnit.Generator.SpecFlowPlugin.dll</_SpecFlow_xUnitGeneratorPluginPath> 
    </PropertyGroup> 
    

    .
    Which plugin to use is determined based on the MSBuildRuntimeType (either “Core” or another value). “netstandard2.0” and “net471” are the directories containing the corresponding DLL for each runtime.

  3. Edit the .props file in your package to include your plugin’s path. You need to add an ItemGroup containing the SpecFlowGeneratorPlugins element to this file.
    Using the .props file for the generator plugin for xUnit (located at /Plugins/TechTalk.SpecFlow.xUnit.Generator.SpecFlowPlugin) as an example, the .props file is configured like this:

    <ItemGroup> 
      <SpecFlowGeneratorPlugins Include="$(_SpecFlow_xUnitGeneratorPluginPath)" />
    </ItemGroup> 
    

    This adds the plugin’s fully qualified path to the list of SpecFlowGeneratorPlugins.

Runtime Plugins

Like generator plugins, runtime plugins are also no longer configured in your app.config file. Instead, SpecFlow loads all files ending with .SpecFlowPlugin.dll found in the following locations:

  • The folder containing your TechTalk.SpecFlow.dll file.
  • The current working directory

To update your runtime plugin:

  1. The actual DLL to reference is determined in the .targets file. You need to load a different version of the plugin depending on the target framework of your project (Full Framework vs .NET Core). Using the xUnit .targets file as an example (the file is here):
    <PropertyGroup> 
       <_SpecFlow_xUnitRuntimePlugin Condition=" '$(TargetFrameworkIdentifier)' == '.NETCoreApp' ">netstandard2.0</_SpecFlow_xUnitRuntimePlugin> 
       <_SpecFlow_xUnitRuntimePlugin Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' ">net45</_SpecFlow_xUnitRuntimePlugin> 
       <_SpecFlow_xUnitRuntimePluginPath>$(MSBuildThisFileDirectory)\..\lib\$(_SpecFlow_xUnitRuntimePlugin)\TechTalk.SpecFlow.xUnit.SpecFlowPlugin.dll</_SpecFlow_xUnitRuntimePluginPath> 
    </PropertyGroup> 
    

    .
    Which plugin to use is determined based on the TargetFrameworkIdentifier (either “.NETCoreAPP” or “.NETFramework”). “netstandard2.0” and “net45” are the directories containing the corresponding DLL for each runtime.

  2. Edit the .props file in your package to include your plugin’s path. Because .NET Core does not copy the referenced files to your target directory, you need to add your runtime plugin to the None ItemGroup and set CopyToOuputDirectory to “PreserveNewest” to ensure the plugin is copied.
    Using the props file for the xUnit plugin (located at /Plugins/TechTalk.SpecFlow.xUnit.Generator.SpecFlowPlugin) as an example:

    <ItemGroup> 
      <None Include="$(_SpecFlow_xUnitRuntimePluginPath)" > 
        <Link>%(Filename)%(Extension)</Link> 
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
        <Visible>False</Visible> 
      </None> 
    </ItemGroup> 
    

Plugin Developer Channel

We have set up a Gitter channel for plugin developers here. If you questions regarding the development of plugins for SpecFlow, this is the place to ask them.