On December 16th I attended a Madriagil meetup. This time we talked about Behaviour Driven Development (BDD). @Laura_Morillo gave us a short introduction to BDD. @plagelao and @ecomba were connected by Skype from Eden headquarters in Winchester. Enrique shared his experience with BDD giving us some examples of test scenarios from Eden projects.
Then we had a look at sample scenarios I prepared for the session. First, I created a simple web application with Grails. The application should create invoices for customers. For sake of simplicity and laziness I implemented only the customer CRUD part (or rather, I used Grails scaffoling to generate controller actions and views). Second, I created a separate project with BDD-style tests with JBehave Web. I was not able to implement and run JBehave Web steps in Groovy. So I put them in different projects.
The application was created not from a customer business need, but to demonstrate BDD vocabulary, scenarios and steps and their mappings to an executable code. I conjured up the code and I was having problem with defining the user story. Finally, during the meeting I came up with this user story that fits into the application:
As accountant
I want to track my customers
So I can invoice them and earn money
(Enrique insisted on business value in user stories and therefore my greediness for money 🙂 ).
Here are my scenarios (in JBehave syntax):
Scenario: Default customer page should be list page When the user opens the customer page Then the customer list page should be displayed Scenario: All customers should be displayed on the list page Given the customers: |name|address| |Marcin Gryszko|somewhere in Las Rozas| |Batmanek|lost in space| When the user opens the customer list page Then the customers listed above should be displayed: |name|address| |Marcin Gryszko|somewhere in Las Rozas| |Batmanek|lost in space| Scenario: Create new customer When the user opens the customer create page And fills the customer name: 'Grzegorz Brzeczyszczykiewicz', address: 'Chrzeszczylewoszyce' And presses the create button Then the confirmation message is displayed And the customer details are displayed: name: 'Grzegorz Brzeczyszczykiewicz', address: 'Chrzeszczylewoszyce' Scenario: Create new customer with empty mandatory fields When the user opens the customer create page And fills the customer name: '', address: '' And presses the create button Then the validation error message is displayed
BDD scenarios should use a natural, problem domain language. They should not be technology agnostic, as Enrique pointed out. My scenarios depend on web technologies – I’m talking about pages, tables, buttons, … I’m opening, pressing, displaying, …
In order to think not in the context of technology, I liked the metaphor of @jmbeas: imagine that your customer management is done via an IVR system. There won’t be no browser – only voice. Thinking of my (web) application as of an application controlled by phone helped me to think in terms of more generic behaviours rather than in terms of behaviours bound to a specific technology.
We started changing the scenarios collectively. We did “All customers should be displayed on the list page” and started with refactoring “Create new customer”. I finished the partially modified scenario and changed the rest as homework. Here are my new scenarios:
Narrative: As a accountant I want to track my customers In order to invoice them and earn money Scenario: Customer list is presented by default When I want to manage customers Then the customer list should be presented Scenario: List all customers Given the customers: |name|address| |Marcin Gryszko|somewhere in Las Rozas| |Batmanek|lost in space| When I request the customer list Then the customers below should be returned: |name|address| |Marcin Gryszko|somewhere in Las Rozas| |Batmanek|lost in space| Scenario: Create new customer When I add a customer with name 'Grzegorz Brzeczyszczykiewicz' living in 'Chrzeszczylewoszyce' Then I should be notified about the successful customer creation Scenario: Create new customer with empty name When I add a customer with name '' living in '' Then I should be notified that the name is empty
I included the story on the top of the scenarios. Note that some scenario names changed too – they are now technology neutral (and they are valid for an IVR system).
I had problem with the first scenario: Default customer page should be list page.
It checks that if user types /customer URL, he will be redirected to customer list (/customer/list).
Would my customer (i.e. the organization that pays for the software) suggest this scenario if the invoicing application had been implemented as a desktop application? Or he wrote it down because he knew that I was going to develop a web application? Or was it proposed by me because I didn’t want to scary the user with 404 error page for /customer URL?
Finally I changed the scenario name to Customer list is presented by default and changed steps to When I want to manage customers and Then the customer list should be presented.
Any suggestions on my refactoring? Can they be improved furthermore? Please share your thoughts in comments (in english, spanish or german).
Buenas, muchas gracias por compartir el refactor 😀
Me gusta como has definido la historia, y me gusta que se refleje la pasta 😀
omo yo lo veo, el primer escenario creo que sobra (Customer list is presented by default). Creo que está incluido en el segundo.
Tampoco hablaría de “Customer list”, hablaría de “Customers” (when I ask for my customers, por ejemplo)
Un saludo
Scenario 1: quizás sobra… Mis dudas he reflejado debajo de los escenarios refactorizados. A ver que dice otra gente.
Scenario 2 y 3: en la metáfora de IVR, la lista puede ser leida al usuario.
Estoy de acuerdo que
When I request the customer list
se podría expresar como:
When I request customers
Dice lo mismo y hay menos palabras.
Hi, Marcin
Thanks for the mention and thanks for sharing.
Given I am stuck looking for a good acceptance test,
When I think in a extremme scenario,
Then I find my acceptance test more easily.
🙂