In a previous post on how to allow Gherkin authors flexibility to write the lines of a scenario in whatever order made sense to them, I suggested deferring things as a mechanism for making this happen. The costs of doing this have become more apparent to me since I wrote that, so I think that you need to weigh them carefully. There are other uses of deferring things in SpecFlow that you should also consider, that are separate from the bits that enable flexibility. The costs are smaller, and there are useful benefits.
A summary of deferring in the scenario set-up
A brief summary of the other post. There is an order in which things must happen when your test is executed – for instance: login to a website, go to a starting page, do some set-up actions, do the action under test, check that you’re on the expected next page. There are details that might need sorting as part of this – which credentials to use when logging in etc. The details are likely to be delivered in some way by the lines of the scenario. The order in which these details are needed by the test might not be the only order in which the corresponding lines of the scenario could be written.
So I suggested using deferring (using C# delegates) as a way of handling the difference in order. You defer for as long as possible actually doing things, while you also gather up the information needed by the test in whatever order it’s presented. Then, when you can’t put things off any longer, you work through your list of deferred operations, and using the information you’ve gathered.
Pros and cons of deferring to cope with information out of order
The advantage of doing this is that it lets you write scenarios in several orders. If you have non-technical people writing them, it might not be obvious to them which order information is needed by the test, so it will help non-technical people write scenarios that don’t need editing by technical people.
The main disadvantage is complexity. There is more code to understand, debug and change. This will take exta time – it is likely that you are under time pressure, and the extra time taken to deal with the complexity could instead be spent writing more tests that are simpler.
There is a less direct link between the Gherkin lines and the actions performed by the test, which will make debugging and changing things harder.
Our Gherkin has all been written by programmers so far, who have found it relatively easy to write even though its order is constrained by the tests’ implementation details.
Deferring tidying up
I have ripped out the deferring code I wrote to handle things being out of order. However, I still have other code that defers stuff for later. This is code to handle tidying up at the end of a scenario.
If a scenario creates something e.g. in the database, after I have tested that the new thing is as I expect, I delete it. To make it simpler to do this, I have a list of things to do at the end of the scenario, which is executed in an end-of-scenario hook. I add to this as soon as I can, e.g. as soon as I know the primary key value of the thing created (and before it has been checked).
Tidying up at the end of a scenario makes my life easier. The scenario can be run as many times as I want, and will behave the same each time. (Test repeatability is nice.) Also, it stops test databases from getting more and more cluttered over time, which makes it easier for me if I need to do manual investigation of what the test’s doing.
The costs of allowing Gherkin to be written in whatever order makes sense to a business person might be worth it for you, but please be aware of them before implementing the mechanism necessary. Even if it’s not worth deferring things to allow for flexible Gherkin, it is worth considering deferring things as a way of tidying up at the end of a scenario.