Clarity, Concurrency, Convenience
I'm currently making some changes to Cucumber godog which is a behaviour driven development tool for golang. Whilst writing some tests I've strrugled to find a nice pattern for shared state across steps.
What is the recommendation when we have a collection of values that we need to share between steps?
A common anti-pattern I've seen in godog usage is just to have a bunch of global variables. This approach has at least one shortcoming in that this pattern doesn't lend itself to parallel execution because global vars would be shared across all threads and so the threads would trample on each other.
Godog, like Cucumber JVM, does provide a better method to share state across just the steps in a single scenario and this approach isn't succeptible to the issues that globals would. You can see examples of this proposal in the godog documentation where "context.Context" is threaded through the steps and and necessary shared state is comunicated by adding it to the context.
However, the godog docs don't provide evolved examples of the practices around the use of the context and only show storing a single primitive value into the context.
But, what do I do when I have a collection of state values that I want to share?
My preferred solution to this is to create a struct that encapsulates all these shared values and which can be added to the context. This is somewhat similar to what we always to in Cucumber JVM.
I then provide a utility function to access the shared state. The pattern I illustrate below is the most convenient I've come up with. This pattern is also convenient in that we can easily trace where the various shared state fields are accessed.