SpecFlow
SpecFlow copied to clipboard
Documentation request: enhance plugin documentation for changing global dependencies
Product:
- [x] SpecFlow
- [ ] SpecFlow+ Runner
- [ ] SpecFlow+ LivingDoc
- [ ] SpecMap
What is missing:
I tried to change the default ITraceListener
like so:
public class CustomTracerPlugin : IRuntimePlugin
{
public void Initialize(
RuntimePluginEvents runtimePluginEvents,
RuntimePluginParameters runtimePluginParameters,
UnitTestProviderConfiguration unitTestProviderConfiguration)
{
runtimePluginEvents.CustomizeGlobalDependencies += (_, args) => args.ObjectContainer.RegisterTypeAs<CustomTracer, ITraceListener>();
}
}
The initialize function gets called and failes, because there is already a ITraceListener
registered.
Documentation should include an example on how to change default objects in the DI-container.
You picked the one interface that can't really be overridden by plugins on another level than on Scenarios. We are using it for logging itself before the plugins are loaded.
What did you try to achieve?
I see you set this in the NUnit plugin.
I would really like to reduce output to a bare minimum for running tests on gitlab for merge request tests.
Ideally we would like to only get output in the form: test X successful and the full output for failing tests.
It would be all right to overwrite it on scenario level I don't need the output of all the successful steps. If I can overwrite it on scenario level and remove most of the output that would be perfect. We have a limit on the log size (trying to remove that, too).
Did you try to turn the tracing off?
https://docs.specflow.org/projects/specflow/en/latest/Installation/Configuration.html#trace
If this is not enough, I think your requirement would be best solved, if you contribute it to SpecFlow. Either use the tracing configuration value in more places or add a new one for the log level.
I did, here's my specflow.json:
{
"language": {
"feature": "de-DE"
},
"stepAssemblies": [
{
"assembly": "SomeAssembly"
}
],
"trace": {
"traceSuccessfulSteps": false
}
}
And I will think about your proposal.
should I file a bug report because traceSuccessfulSteps
has no effect?
Before that, can you check your specflow.json file is in the output folder? To be sure where the error is.
I came across this issue a few times while looking for a way to inject an ITraceListener
to capture start/end of step logging.
(we were previously using the <trace listener="..." />
config option in Specflow 2 but can't use that anymore with Specflow 3)
Turns out that start/end of step logging is done using the ITraceListener
instance of the "test thread" container.
Reproducing our solution here just in case it helps the next person (although I'm not sure if this is a stable solution. It looks like the nunit/xunit/mstest plugins also override ITraceListener
. I don't know if the order of loading their plugin and our own CustomTracerPlugin
is well-defined):
using TechTalk.SpecFlow.Plugins;
using TechTalk.SpecFlow.Tracing;
using TechTalk.SpecFlow.UnitTestProvider;
[assembly: RuntimePlugin(typeof(CustomTracerPlugin))]
public class CustomTracerPlugin : IRuntimePlugin
{
public void Initialize(
RuntimePluginEvents runtimePluginEvents,
RuntimePluginParameters runtimePluginParameters,
UnitTestProviderConfiguration unitTestProviderConfiguration)
{
runtimePluginEvents.CustomizeTestThreadDependencies +=
(s, ea) => ea.ObjectContainer.RegisterTypeAs<OurNameSpace.OurClassName, ITraceListener>();
}
}
namespace OurNameSpace
{
public class OurClassName : ITraceListener {
// Implementation
}
}
You picked the one interface that can't really be overridden by plugins on another level than on Scenarios. We are using it for logging itself before the plugins are loaded.
Before finding the above solution, I tried to override the ITraceListener
instance in the global dependency injection container.
Doing it via a runtime plugin did not work indeed.
However, I did find a way using the specflow.json
config.
It looks like the JsonConfigurationLoader
registers any (implementation, interface)
pairs that are specified in runtime.dependencies
.
In our case, we got that to work with the following specflow.json
:
{
"$schema": "https://specflow.org/specflow-config.json",
"runtime": {
"missingOrPendingStepsOutcome": "Error",
"dependencies": [
{
"type": "OurNameSpace.OurClassName, OurAssemblyName",
"as": "TechTalk.SpecFlow.Tracing.ITraceListener, TechTalk.SpecFlow"
}
]
}
}