I had the pleasure of speaking at CukeUp! this year (2015), the fifth edition of Cucumber's conference which is more about BDD than Cucumber itself, although there are always updates on the state of the tool (this year Matt released version 2.0 during his talk!)
Borja and I
It's been a great conference, I've learned a bunch of things, met friends and new people. My colleague Borja Navarro accepted the challenge of co-presenting with me and that made our session fun, a least for me, a had a lot of fun. We engaged the attendees with a couple of examples together with questions and answers on how to write user stories with acceptance criteria and scenarios. The attendees were very helpful and active. This is the recorded session, although the sound is quite bad.
Thank you Borja, you rock mate!
These are my conference picks:
- A mature XP team don't need to have people exclusively for testing and QA purposes. If every developer has testing skills and every pair is responsible for quality then people just play the two roles but there is no such distinction between testers and developers. There will be people with stronger development skills and people with stronger testing skills, experts on each area. Well, this is my understanding from Rachel's and Aimy's keynote.
- They don't have a staging environment, they release directly into production, performing some smoke testing live with some "testing" user accounts. I find this technique specially interesting when the new features can be deployed just on a few servers so that only certain users get to exercise the new code whilst the others keep using the previous version for a while. Exploratory testing and other tests are performed on the development environment. The maturity level of the team has to be very high, sounds like a nice goal to reach at my current project.
- I participated in Paul Rayner's useful workshop, specially nice because I got the chance to share table with Steve Tooke and Gáspár Nagy, experts on the subject. My pick is that any technique that could help with discovery during the analysis stage is welcome. One of the suggested techniques was Event Storming, which I am going to trying as soon as I can. Since we are using DDD in our project, Event storming sounds like a great technique to combine analysis and modeling.
- From Seb's talk there are many ideas to take away, it's worth reading the slides. I already listened to his talk in a previous event in London and I want to read the recommended books. Take a look at this map on how to split user stories.
- Konstantin Kudryashov, creator of Behat, gave an interesting talk on how to explore and exercise the domain model from Gherkin scenarios, the slides are here. My understanding was that he uses domain objects within the step definitions as if these steps were unit tests. The approach is a bit different from the one we are using where the step definitions invoke actions on application services rather than objects from the inner hexagon. Although we use application services we usually stub out or spy on repositories aiming for fast tests. Another technique he employs is to mark a few scenarios as critical making them run end-to-end through the UI so as to make sure all pieces integrate with each other. It's good to know the techniques that are working for other people and see how they are different to the ones we currently use.
- The keynote by Dan North was full of insight, I highly recommend watching it. I didn't watch it live as I prefer to chat with people whilst talks are being recorded - at that time I took the chance and enjoyed listening to Chris Matts in the bar. To me, the most interesting tip is the experiment Dan is conveying where every team member's board has to have Kaizen tasks, Discovery tasks and Feature tasks. Brilliant, isn't it?
- The workshop by Chris Matts and Richard Warner was full of insightful ideas. I liked the exercise on "Left Shifting" company's culture. On the other hand they explained their discovery process when it comes to feature analysis. The three keys to discover new features are "Customer needs and wants", "Target group" and "Outcome". The workshop was recorded, it's worth watching that part of the session which was more of a talk than a workshop. My understanding is that they are not using user story mapping at all. It was really nice to share table with Nat Pryce during the workshop, he was very active and fun, I am glad I got to know him in person finally.
- Matt Wynne's workshop was one of my favorite ones. I really like the password strength exercise to illustrate the difference between acceptance criteria (rules) and examples. See these slides for more details. The other pick is "Example mapping" a technique where the colors end up making obvious what we know and don't know about the context in order to write good user stories. I also realised that the examples used for exercises may work better when they are fun, when we add some humor to them. Writing user stories for a boring domain is not as engaging as writing them for some fun domain with curious situations.
At the end of the conference there was a panel with the experts, the creators of BDD. As a result Dan North came up with this initiative on explaining BDD by example. I want to contribute to those examples. By the way, Dan said he found John Ferguson's book very good, I have to check it out.
CukeUp brought me more value than I expected, I am glad I was part of it. Thank you organisers, you made a great job!
Este post habla de dos de los valores de XP: Simplicidad y Feedback. Fundamentales y habitualmente olvidados.
Cuando escribimos software o dibujamos una interfaz de usuario, estamos dando forma a una solución concreta de las muchas que puede tener un problema. Al elegir una solución automaticamente descartamos las demás porque nunca damos marcha atrás para escribir otra solución distinta si la que tenemos ya “funciona”. Por esto hay que reflexionar constantemente sobre la complejidad de la solución que hemos elegido. Lo mejor es hablarlo con los compañeros, discutirlo. A menudo exponiendo la idea descubrimos que podemos conseguir lo mismo de una manera más sencilla.
La clave para poder simplificar es tener en cuenta cuál es el objetivo (qué problema fundamental estamos resolviendo) de negocio. Pero no el objetivo del software a largo plazo sino de la release actual. Lanzamos releases frecuentes en ciclos cortos para obtener feedback y cada una tiene el objetivo de aprender algo concreto del negocio o de los usuarios. Cada release ofrece alguna caracteristica nueva o un cambio que les ayude en su día a día pero sin querer abarcar demasiado de un golpe. Me gusta que la lista de features y cambios de una release me quepa en la cabeza, que pueda contar con los dedos de una mano sin necesidad de documentos. Y que haya un objetivo predominante.
Para simplificar hay que tener en mente cuál es el objetivo de la release actual, que no es el mismo que la release que haremos dentro de 3 meses. De aquí a 3 meses habremos cambiado buena parte del código, a veces mediante refactoring y a veces porque nos damos cuenta de que hay otras necesidades. La vida cambia en 3 meses y en menos.
Conviene darle más de una vuelta a la solución, hay que “resimplificar” todo lo posible. Lleva poco tiempo hacerlo y tiene un beneficio muy grande en el medio y largo plazo. "Vale ya funciona, ahora vamos a echarle una pensada para ver si lo podemos simplificar, a ver si podemos borrar la mitad del codigo y que siga funcionando".
El código tiene que quedar fácil de entender y su simplicidad es más importante que el uso de patrones. No tenemos por qué aplicar el patrón MVVM en absolutamente todas las partes de la capa de presentación, a veces su complejidad no se justifica. Por cierto, recordemos que un ViewModel es una representación de la vista y no un DTO, un ViewModel es una especie de "controller".
La soluciones deben ser lo más abiertas posibles para poder dar margen de maniobra al usuario y aprender cual es su forma preferida de trabajar. Hay que identificar limitaciones innecesarias que estemos introduciendo tanto a traves de al interfaz de usuario como a nivel del código para poder evitarlas. Una solución abierta se centra en el problema a resolver, en el “qué” y permite cambios de forma con facilidad, poder pivotar hacia otras cosas.
Por ejemplo, imaginemos que hay 3 acciones fundamentales que el usuario puede realizar en la aplicación. No hace falta que las realice en un orden concreto, el objetivo de negocio es que pueda realizar las acciones A, B y C cuando mejor le convenga. Entonces no hagamos que para ejecutar la acción A, tenga que hacer primero la B. Eso es introducir una limitación innecesaria.
Ahora un ejemplo de complejidad excesiva: Imaginemos que queremos mostrarle al comercial la disponibilidad de un determinado modelo de vehiculo, es decir, si está en stock. El objetivo de negocio es que sepa si puede vender ese modelo o no. ¿Para qué vamos a contar cuántos vehículos hay disponibles de ese modelo? Le da igual si hay 24, solo necesita saber si tiene una unidad disponible para la venta o no la tiene. Para darnos cuenta de este exceso de complejidad tenemos que recordar el objetivo de la release. Recordar el propósito de la release actual.
Cuanto menos software escribamos mejor. La linea que no falla es la que no está escrita. Cada linea que escribimos es un compromiso que hay que mantener, hasta que alguien venga y la borre. Cuanto vamos justos para cumplir con el objetivo de la release (en el mundo del software esto es siempre), debemos recortar en alcance (funcionalidad) y nunca en calidad. Hay que hacer todo lo posible por respetar los tiempos de entrega previstos, consiguiendo el objetivo a base de quitar características menos importantes en el momento actual.
This is the first of a series of posts on how our team is practicing BDD. These are mostly notes to myself and our team so other readers may not find enough context to understand the points.
After a few weeks we have decided that:
- Although source code is written in English, the specifications are written in Spanish. Because the business is always discussed in Spanish, it's the language used to determine what we need to do. So the Cucumber scenarios are written in Spanish.
- There is a glossary of business terms to help us document the ubiquitous language. The glossary contains the translations from Spanish to English so that the source code expresses the same concepts.
- If developers need to change or adjust the scenarios for some reason (for instance, automation purposes), then business analyst have to validate the changes.
- Scenarios will be stored in only place only, and that place is SpecFlow (Cucumber). This means that business analyst need to have all the tools installed and access to the source control repository (Visual Studio and TortoiseHG).
- After the specifications workshop, scenarios are written in pairs or groups of 3 or 4 people. Two people is usually enough. We've realized that writing the scenarios in pairs help us come up with more questions and more ideas to simplify the problem.
- The automation of the scenarios should also be done in pairs, because this is yet another opportunity for us to detect inconsistencies or doubts. Well, in general we just pair most of the time.
- A user story is not ready for implementation until it's got at least 4 scenarios. We started with just one and the lack of context caused us to introduce wrong models in the code. Actually when test-driving a small function, we never start out with a single example but with a to-do list. Then we focus on each test writing the minimum code required but we do know where we want to go. This is the same but at a higher level.
- Given that our business analyst know how to read code, they should read the source code at the end of the iteration. By reading the part of the code inside the hexagon (we use hexagonal architecture), they can ensure the designed model makes sense.
- Scenarios should not repeat irrelevant details. If one scenario uses real data like a "plate number", then the following scenarios don't need to repeat the whole plate number but just something like "x". We should keep in mind that scenarios complement each other in terms of documentation. They should be indepdendent for execution but not for documentation.
- Triangulation: we can make a scenario go green quickly. However, triangulating the code that really works for all the cases falling under that scenario, may require more code. If the triangulation does not concern business details, we use NUnit to test-drive rather than SpecFlow. Scenarios are used for documentation, not for triangulation, unless the triangulation covers relevant business tips.
It was by chance that one of our business analysts came up to a mob programming session and got to see code related to the scenarios that we had defined together. Quickly he realised that we were introducing aliens in the domain (wrong models). It was because we were lacking some other scenarios. The fact that the code was in the wall with a massive font size and it really communicated our intent, together with the fact that the reader is very clever, made us discover an useful technique to double-check our assumptions.