There has been a lot of debate in the past about which style is good and which is bad. If I were to ask a developer or a QA to write a scenario, I can rest assured that it will be an Imperative style whereas a BA or an end user would probably adopt a declarative style. There is no, one is better than the other, both styles have their advantages and disadvantages. This article talks about achieving a middle ground to reap the benefits of both styles.
An imperative styled scenario is more appealing to a reader who wishes to understand the “Hows” of the system because it is generally detailed around the mechanism whereas a reader who just wants to understand the “Whats” of a system would prefer a declarative style.
Writing everything in a declarative style or in an imperative style is not an ideal. In a real world situation, not all users/readers are either purely business oriented or purely technical oriented. In practice we know that there is always some level of overlap and at times a lot of overlap, which majorly depends on the domain itself. A technical person who has grown into being a BA or a product manager would not mind a mid-level between the two approaches. Sometimes it is necessary for a BA to get a sense of the “Hows” to a certain extent in order to understand the dependencies between stories/scenarios. A level that is not too abstract for a technical user and not too detailed for a BA would be beneficial. This balanced level has the ability to really “bridge the gap” between the business and the development teams.
Now, lets look at how Twist helps us achieve the right level of abstraction without having to throw away any existing work, whatever level of abstraction it is at.
Here is a simple login scenario that can be expressed at different levels.
This scenario clearly describes the action and how to perform them on the target application. It is implementation detail oriented. From this scenario I know that username and password fields are text boxes and password field is a password type text box that masks characters. i also know that the sign-in action is on a button and not a link. From the verify statements at the end, I also know the various things I am verifying in order to make sure a user is actually signed-in or setting a clear expectation with the development team that unless these things are verified, the user is not actually considered signed in.
This scenario is business user oriented, very abstract and gets rid of the implementation noise totally. It simply describes user interaction at a high level and the expected outcome. There is nothing explicit here, everything is implied. What the author really implies is not conveyed here fully. If this is my executable acceptance criteria and a dev camp reads this, they will come up with tons of questions on the hows and what ifs or in the worst case will assume. Does credentials have only username and password only or with a PIN? etc.
This scenario gets rid of implementation detail but retains some details that are business critical or that ideally should be explicit. Readers can still make assumptions here about sign-in being a button or a link and its ok as its not business critical (because they both work) and they don’t have to make any assumptions about the kind of credentials used to authenticate.
Consider the above login scenario. Let’s say you have written the scenario in an imperative style as below.
Now how do I make this business readable or declarative in style? without having to change this or rewrite this, with minimal changes only if necessary. This is where twist’s Concepts come to the rescue. Twist has an intent level feature called “Abstract Concepts” aka “Extract Concept”. The following example shows how this is done.
Twist lets me select one or more statements in a workflow and create a reusable concept. In this example above, we will look to create 2 concepts. Let’s group/select all the verify statements and extract them as a “Verify that user is signed in” or even simply “Verify login” concept.
The workflow then becomes …
Let me now create another concept called “Using user credentials” by selecting/grouping the first two statements. The scenario them becomes…
I’ll further, rephrase the second statement here as “Verify that password entered is not user readable” and the third statement as “Sign in to the system”. The workflow now looks like this….
The scenario now looks more business readable. A user who is more technical and wishes to understand the implementation details can open these concepts and see the steps within them and the code eventually backing these intent.
In twist, I can in fact further create a concept out of all these steps as follows…
Thus, using the power of Abstract Concepts, you can create any level of abstraction you wish in your scenarios.
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.