Imperative Vs. Declarative style of writing Twist scenarios
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.
Imperative level
Login:
- Enter username into username text box
- Enter password into password text box
- Verify that password text is dotted
- Click on signin button
- Verify that username is displayed
- Verify that welcome message is displayed
- Verify that signout link is displayed
- Verify that user has access to his profile
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.
Declarative level
Login:
- Using user credentials
- Sign in
- Verify that user is 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.
A Balanced level – midway
Login:
- Using username and password
- Verify that password entered is not user readable
- Sign in to the system
- Verify that a user welcome message is displayed
- Verify that user has access to his profile
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.
Example
Consider the above login scenario. Let’s say you have written the scenario in an imperative style as below.
Login:
- Enter username into username text box
- Enter password into password text box
- Verify that password text is dotted
- Click on signin button
- Verify that username is displayed
- Verify that welcome message is displayed
- Verify that signout link is displayed
- Verify that user has access to his profile
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 …
Login:
- Enter username into username text box
- Enter password into password text box
- Verify that password text is dotted
- Click on signin button
- Verify login
Let me now create another concept called “Using user credentials” by selecting/grouping the first two statements. The scenario them becomes…
Login:
- Using user credentials
- Verify that password text is dotted
- Click on signin button
- Verify login
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….
Login:
- Using user credentials
- Verify that password entered is not user readable
- Sign in to the system
- Verify login
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…
Login:
- Perform user login and verify the same
Thus, using the power of Abstract Concepts, you can create any level of abstraction you wish in your scenarios.
The just-released collate verification failures without halting the scenario.
Try Twist now to improve test automation and fine-tune your CD process.
Disclaimer: The statements and opinions expressed in this article are those of the author(s) and do not necessarily reflect the positions of Thoughtworks.