Question

For my SpecFlow tests, I want to setup an individual logging / tracing of the test progress during the execution of tests. E.g. i want to write

  • all passed / failed steps
  • started / ended scenarios
  • started / ended features

to the windows event log (in order to synchronize it with event log messages generated by other system components during the test).

I tried to use the [BeforeFeature], [BeforeScenario], [BeforeStep] Hooks for doing that, but it turned out that I do not have all the required information within this hooks. E.g. i do not know how to get the current text line of the current step executed (including line information, etc.) or the result (failed / passed) of the current step.

Is there a way to get this information within those hooks or in any other way during the execution of the test?

If not: Is there a way to customize the trace output created by Specflow in any other way?

Was it helpful?

Solution

In order to provide a custom implementation of ITestTracer you should create a plugin for SpecFlow.

Create a class library project with a name CustomTracer.SpecflowPlugin. CustomTracer is your name of choice for plugin.

Then put the following code into your new assembly

[assembly: RuntimePlugin(typeof(CustomTracer.SpecflowPlugin.CustomTracerPlugin))]

namespace CustomTracer.SpecflowPlugin
{
    public class CustomTracerPlugin : IRuntimePlugin
    {
        public void RegisterDependencies(ObjectContainer container)
        {

        }

        public void RegisterCustomizations(ObjectContainer container, RuntimeConfiguration runtimeConfiguration)
        {
            container.RegisterTypeAs<CustomTracer, ITestTracer>();
        }

        public void RegisterConfigurationDefaults(RuntimeConfiguration runtimeConfiguration)
        {

        }
    }

    public class CustomTracer : ITestTracer
    {
        // Your implementation here
    }
}

Compile assembly and put in the project folder where your specs are (where .csprog file is).

Edit app.config, specFlow section to include:

<plugins>
  <add name="CustomTracer" path="." type="Runtime"/>
</plugins>

That is it. Your plugin should load and your custom ITracer implementation should be called during scenario execution. You can even debug it, if you run scenarios under debug.

OTHER TIPS

Finally, after some investigation, i found out that you can replace the DefaultTraceListener by your own implementation by implementing the Interface ITraceListener:

public class foo:  TechTalk.SpecFlow.Tracing.ITraceListener
{
    public void WriteTestOutput(string message)
    {
        EventLog.WriteEntry("mysource", "output: " + message);
    }

    public void WriteToolOutput(string message)
    {
        EventLog.WriteEntry("mysource", "specflow: " + message);
    }
}

And modifying your App.config configuration by adding this to the "specflow" section:

<trace traceSuccessfulSteps="true"
       traceTimings="false"
       minTracedDuration="0:0:0.1"
       listener="MyNamespace.foo, MyAssemblyName"/>

However, this is more a "workaround" for me since I don't have typed information (e.g. of the StepInstance class) and I have to rely or modify the output formatting of SpecFlow.

I would prefer replacing the TestTracer (ITestTracer) implementation by my own one in some way, but i did not find a way to do this. Does anyone now how to do it?

In Specflow 2.1 its a little different.

Instead of:

public class CustomTracerPlugin : IRuntimePlugin
{
    public void RegisterDependencies(ObjectContainer container)
    {

    }

    public void RegisterCustomizations(ObjectContainer container, RuntimeConfiguration runtimeConfiguration)
    {
        container.RegisterTypeAs<CustomTracer, ITestTracer>();
    }

    public void RegisterConfigurationDefaults(RuntimeConfiguration runtimeConfiguration)
    {

    }
}

Do this:

public class CustomTracerPlugin : IRuntimePlugin
{
    public void Initialize(RuntimePluginEvents runtimePluginEvents, RuntimePluginParameters runtimePluginParameters)
    {
        runtimePluginEvents.CustomizeTestThreadDependencies += (sender, args) => { args.ObjectContainer.RegisterTypeAs<CustomTracer, ITestTracer>(); };
    }
}

Every thing else is the same as Vladimir Perevalovs answer.

To register a custom ITestTracer in SpecFlow 3.x:

[assembly: RuntimePlugin(typeof(CustomTracerPlugin))]

public class CustomTracerPlugin : IRuntimePlugin
{
    public void Initialize(
        RuntimePluginEvents runtimePluginEvents,
        RuntimePluginParameters runtimePluginParameters,
        UnitTestProviderConfiguration unitTestProviderConfiguration)
    {
        runtimePluginEvents.CustomizeGlobalDependencies +=
            (s, ea) => ea.ObjectContainer.RegisterTypeAs<CustomTracer, ITestTracer>();
    }
}

public class CustomTracer : ITestTracer
{
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top