During the last week, there was a Behavior Driven Development (BDD) related question on one of my mailing lists. For me it expressed a large misconception about BDD that is so widespread, and so common. Let’s see what it is, and what to do about it.
Here is the relevant part of the original mail:
Basically, the requirements is to ensure a user is redirected back to the product (eBook) page after they register a new account. Login/registration page is the same page.
GIVEN I am a non-logged in user
AND I am not remembered
WHEN I try to add an item to my “Must read list”
THEN I am directed to the eBook store login/registration page
AND I complete the registration
AND I am redirected back to the eBook page I started from
AND the product will be added to my “Must read list”
Can you spot the problem? Here’s a challenge, before reading further, try to come up with a better solution. Everything’s there that you may need to know to improve it.
Done? Good. Let’s see which smells I can identify.
Impersonalized
“Given I am a non-logged in user” is an impersonalization. It describes the setting of who the “I” is. In most cases, I found that such statements can be reframed to ‘When a non-logged in user tries to add an item to his “Must read” list’ for example. Basically there is no need for the “I” in the scenario, and often it leads sentences like the one above. Replace “I” with the user you are talking about.
Passive voice
I was taught that passive voice should not be used. Like the previous sentence, by using more active statements, you get way better scenarios. “Then the website redirects the user to the registration/login page”, “And the “Must read” list contains the product”, … Active voice improves the readability of the scenario to a big deal.
Details
The scenario is very detailed. It contains a lot of unnecessary details. For example the fact that the user is not logged in, includes that he is not remembered to me. The fact that I am redirected to the login/registration page, and login, and am redirected back to the original page, seems to be a single action that happens from the user goal perspective. Overall this leads to a long scenario. Over the years I have seen scenarios that consist of 100 lines of step definitions and more. Usually there is a pretty good reason why people come up with scenarios like this. I am happy with this, as long as they don’t claim to do ATDD or BDD just because they use a tool developed for BDD.
This leads me to the real problem, the process problem.
“Our testers can’t write code”
Now, here’s the problem, whether you like it or not: your testers are writing code in those BDD tools. They are programming. This is widespread knowledge. For example, lesson 118 in Lessons Learned in Software Testing says it clearly.
What’s even worse with the illusion that your testers can’t write code, and asking them to automate tests in such a way is this: The tools are not as powerful as a developer’s IDE. Even if they were, our industry would still be ending up with unskilled people writing code. I have worked with unskilled programmers over the years. Usually they produced what is known as Legacy Code. Code that starts to slow you down. Did you ever experience something like that in test automation? Test automation that slowed you down?
That leads us to the next problem: When your business relies on the production code, and that code slows you down dramatically, what do you do about it? Exactly, you get someone in helping you with that problem since it has a large business impact. Whether you believe that a single day training helps you, or someone should coach you on how to do it, doesn’t matter. You do something about it to improve it.
What happens when you face a problem with your test automation code that slows your business intake down? Very few do the same, and get someone in to help them. More often, you curse test automation as the culprit, give up your test automation efforts, and stick with manual testing. If that slows you down, you skip tests. Reframed: you skip addressing some of your risks. I can’t evaluate whether you really can allow yourself to do that.
There really is only one way out of this: train your test automators in enough coding so that they can write down reasonable scenarios, are aware of the shortcomings, and have enough design background to refactor the code smells they are creating, and can transfer that knowledge to their scenarios.
Forgotten business goal
The biggest problem with the initial description lies in the mismatch between the scenario, the stuff with the given/when/then in it, and the description in front of that. Let’s take another look:
Basically, the requirements is to ensure a user is redirected back to the product (eBook) page after they register a new account. Login/registration page is the same page.
GIVEN I am a non-logged in user
AND I am not remembered
WHEN I try to add an item to my “Must read list”
THEN I am directed to the eBook store login/registration page
AND I complete the registration
AND I am redirected back to the eBook page I started from
AND the product will be added to my “Must read list”
The business goal of being redirected back to the product page is not obvious in the scenario. If you face that scenario later, then you will have a hard time understandings the business goal. Why couldn’t we just express that? It turns out we can:
When I register a new account from a product page
Then I am redirected back to the product page
There are still a bunch of the smells I mentioned. But the original business goal is now clear. Of course, there are now things you need to hide in step definitions, and of course your testers need to be able to write enough code so that they can deal with the situation.
Events
What most people do not know is that BDD consists of a combination of TDD, ATDD, DDD, Specification Workshops, and outside-in development. That said, it helps to take a closer look on the events that are happening, and try to express the outcomes as messages that should be forwards from your different bounded contexts in your application. Let’s see how that situation could turn out for the example:
Given a non-logged in user adds a product to his “Must read” list
When the user registers a new account
Then the user is redirected back to the product page
And the product is added to his “Must read” list
In the given and when parts we now have events that happen inside your domain, and could be fired in your solution. DDD calls these domain events, since they are something relevant that happens in your domain. The then part also consists of events, but these are raised by your solution.
Stop claiming BDD if you are not
That last example serves the point that you shouldn’t claim to be doings BDD if you are not. Just because you found some shiny tool that helps you write fluent text that is executed, and can be used as regression test tool does not mean that you are doing BDD. BDD foremost starts with a conversation with your customer, users, and clients. If you sit down on your own computer and try to build a prototype with a BDD tool, then you are not doing BDD. From my perspective you are not even yet doing ATDD, either. But this is probably a loaded discussion for another day.
Recent Comments