Are there any global properties that a Gherkin scenario should fulfill? A short answer is, no.
A longer answer is that there are some properties that are good and probably useful in many different contexts.
The outcome of a scenario is the most important part - always start with the end in mind. What will this example demonstrate about the program that we haven't seen yet? How will this example drive our implementation in the right direction? The result is more interesting than the journey in development. Always make sure you know what you want to see as end result.
Scenarios must be concrete - you can't use an ambiguous example for testing. Something that has to be interpreted can't be used as a base for automation.
The opposite of concrete is vague. Is there anything less useful when you try to achieve a concrete result than a vague description? I don't think so.
Scenarios must not contain implementation details - always ask yourself "Can I use this scenario, without changing it, to verify the behavior through the user interface as well as directly in the model?" If you want to change the words because of the place where you connect to the system then you have a scenario that needs better wording.
If you include implementation details in your scenario, you have already decided on the implementation upfront. This is the wrong way of doing things. Always make sure that your scenario are implementation agnostic.
Scenarios must not contain irrelevant details - are there anything in your scenario that is obvious for anyone who knows the domain? If so, don't include it. Your product owner or business analyst will know. They can point at details that are obvious.
An example is a scenario where a password should be changed. Changing a password means that a user must exist. Setting up a user properly can be hidden from the scenario. It is not something that needs to be part of the given context.
Scenarios has to be easy to understand. If you dilute them with too many irrelevant details, they will be harder to understand. Behaviour-driven development, BDD, is a communication tool. The communication breaks when your communication is hard to understand. Always make yourself as easy to understand as possible.
Preparing backing data stores must not be part of a scenario - the data store may be a database but it can also be a stub. These details must be hidden from Gherkin.
This is exactly the same as omitting the obvious. Including unimportant things just makes your message harder to understand. Software development is hard enough without making it harder to understand.
Scenarios should be possible to fit in your head - they have to be short but still meaningful. A scenario longer than 5 lines may be too long and contain too many irrelevant details.
Most people can handle 5 ± 2 things. Scenarios longer than 5 lines will be unnecessarily hard to understand. Make your long scenario short so they are easy to understand. But be careful so you don't make it too short.
5 is just a heuristic and not a rule. If you have to, let your scenario be longer. But use 5 as a warning sign that says: "Hard to understand Gherkin ahead!".
Each Execution of a scenario must be fast - you should not have to wait a long time for feedback. If the scenario fails, you need to know within seconds. Preferably milliseconds.
Long feedback cycles is a road to catastrophe. Make sure you keep your feedback loop as short as possible.
What is long then? It is longer than sub seconds. With lots of tests, the total time accumulates in a bad way. Build times of hours aren't unusual. They are no longer the path to catastrophe, they are a catastrophe.
The diagnose precision must be high - you should not have to troubleshoot a failing scenario. Prefer connecting to the system as close to the actual execution point as possible. Avoid using the user interface as entry point.
No one likes trouble shooting. Make sure that your scenarios have as few reasons as possible to fail. The fewer, the better diagnosis precision.
Connect to the system the same way as your users will connect to it - verifying that it is possible to start and use the system is extremely important. A system where every piece is perfect but not properly assembled is useless.
At the end of the day, it is how your users use the program that matters. Make sure you know that they will not find a surprise. A surprise that is a surprise for all involved, including you and your team.
Some of these properties are contradictory. This is one reason why it is important to remember to have the right number of executions at the right level of the system. Too many slow and brittle executions through the user interface is problematic. Too few executions through the user interface is also problematic since we don't know if the pieces are properly connected.
Remember, our ultimate goals is to create and deliver working software that supports our users. BDD may help you but it is only a tool. A good tool, but still just one way of achieving the ultimate goal, good programs for our users.
I would like to thank Malin Ekholm for proof reading.