LivingDoc Implementation (Fix for skipped steps and missing error messages) #355
Replies: 3 comments
-
|
@Registeel Thx for sharing! |
Beta Was this translation helpful? Give feedback.
-
|
@Registeel Thank you for the detailed and very helpful insights! There is a small issue in the [BeforeScenario] handler: in your example above the feature.Title is used twice as an argument when constructing the ExecutionResult instance but the scenario title should be used instead: [BeforeScenario]
public void BeforeScenario(FeatureInfo feature, ScenarioInfo scenario)
{
var skipHandler = new SkippedStepHandler();
this._objectContainer.RegisterInstanceAs<ISkippedStepHandler>(skipHandler);
_result = new(
ExecutionContextType,
feature.FolderPath,
feature.Title,
feature.Title, // should be scenario.Title
scenario.Arguments.Values.Cast<string>().ToArray());
this._objectContainer.RegisterInstanceAs(_result);
} |
Beta Was this translation helpful? Give feedback.
-
|
@Registeel FYI: there is a small issue that I ran into when upgrading to ReqNRoll v2.3.0: As the deprecated dependency to Specflow.Internal.Json has been removed in ReqNRoll v2.3.0 this code from @dakiers project in LivingDocHooks.cs won't work anymore: [AfterTestRun(Order = AfterOrder)]
public static async Task AfterTestRun()
{
_execution!.GenerationTime = DateTime.UtcNow;
await File.WriteAllTextAsync(FileName, _execution.ToJson(new(false)));
}As an alternative System.Text.Json.JsonSerializer can be used (as discussed here). The example below uses the JsonStringEnumConverter so that enum values will be serialized using their string representations (which is what the removed Specflow.Internal.Json dependency did, otherwise the generated file won't work properly with LivingDoc): [AfterTestRun(Order = AfterOrder)]
public static async Task AfterTestRun()
{
_execution!.GenerationTime = DateTime.UtcNow;
// See https://github.com/orgs/reqnroll/discussions/68 - write json file to support LivingDoc
var serializerOptions = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = true,
Converters = { new JsonStringEnumConverter() } // do not use underlying enum values, use the string representation
};
await File.WriteAllTextAsync("TestExecution.json", JsonSerializer.Serialize(_execution, serializerOptions), Encoding.UTF8);
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I have taken an implementation of @dakiers project that generates the TestExecution.json file that is required to run SpecFlow+ LivingDoc with test results. I added everything but the "Hooks" directory to a class library then added the hooks to my existing reqnroll project and it worked great for generating the TestExecution.json file.
There are issues I found that I have resolved in this implementation.
step.TestError?.Messageis always empty so errored steps give no output.I've resolved both of these issues. I'll start with the first problem.
Skipped Steps
The issue with skipped steps is that they are not processed in the
[AfterStep]hook. So once you hit a failed step, all the skipped ones afterwards are not recorded in theExecutionResultobject that is written to in the[AfterStep]hook like so:The solution for this problem is to build a custom SkippedStepHandler. This is a custom class with any name you like that inherits the reqnroll
ISkippedStepHandlerinterface.My implementation looks like this:
The confusing part about this is where the ExecutionResult is coming from. This is what is used to record the step status to write to the TestExecution.json file. We need to pass this object by reference from the main reqnroll hook file that is running the tests.
I have done this in my
[BeforeScenario]hook from dakiers project like so:The _objectContainer is an instance of an IObjectContainer that is dependency injected into the main Hook class.
With this setup the _result object is passed to the custom handler and when skipped steps are hit they are written to the result before being written to the TestExecution.json file in the
[AfterScenario]and[AfterTestRun]hooks.Onto problem number two.
Empty Error Messages
This one was a simpler problem. Essentially
step.TestError?.Messageis always empty, but you do get an error message for the failure of the step in your Scenario Context.My solution is to change
step.TestError?.Message, (stepcoming fromvar step = scenario.StepContext), toscenario.TestError?.Message.If you would like extra logging I also appended
scenario.TestError?.InnerException?.Messageto mine.Beta Was this translation helpful? Give feedback.
All reactions