When BDD scenarios are turned into executable automated tests, they usually automate the application together with its dependencies (e.g. end-to-end with browser automation or headless with controller-layer automation). This ensures that the application works as a whole, but unfortunately it also makes the analysis of a failing test harder. So many things can go wrong, especially if you run these tests on a build server, where the monitoring of the different actions is limited. Because of this, providing more information on the context where the error has happened (screenshot, log, last transaction, etc.) is really helpful. In this post I show you how this can be done.
For collecting more information on the error context, the [AfterScenario] hooks can be used. You might not know, but the [AfterScenario] hook is also executed when the scenario has failed. So in some sense it behaves like the finally block in C#. If there was an error, the TestError
property of the current ScenarioContext
contains the related exception, so this property can be used to decide if the hook runs for a failing scenario.
The concept is simple enough, but there are still some interesting questions that should be answered:
- Where to save the generated files?
- How to generate a meaningfully unique file name, which can be used to identify the failing scenario even if there are multiple failures?
- How to link the file to the output report?
In the following example I will show a complete solution to save a screenshot of the web browser on error. This example should also answer the questions above.
These are a couple of lines of code, but hopefully not that complicated. The key points are:
- It saves the screenshot to the right place, using the
TestFolders
helper class I have described in this earlier post. - It generates a unique file name based on the feature and the scenario name, so it will be easy to identify the generated file. The
ToPath
method is a simple helper method that removes any character from a string that is not valid in file names. (See the method implementation here.) - It emits the generated file path (as a
file://
URI) to the console output. Some test runners (like the SpecFlow+ Runner) might pick up these links in the output and display them as an attachment. - If you want to be better prepared for parallel execution, you can inject the scenario and the feature context instead of using the
ScenarioContext.Current
andFeatureContext.Current
properties. See the details of this in this post. - You can also save the source code of the currently rendered page by saving the value of the
myWebDriver.PageSource
property.
Using [AfterStep]
The failing step can usually be identified on the basis of the stack trace. However, if you use the same step multiple times, this is not very easy.
SpecFlow v2 can also provide information on the currently executed step, so we can further improve our tracing by using the [AfterStep] hook instead of the [AfterScenario] and trace the information about the failing step.
The [AfterStep] hook behaves similarly to the [AfterScenario], so it is also executed when there was an error. So everything we have seen for error handling in the [AfterScenario] hooks works for this one as well.
Continue reading the second part of the article here.