I've just finished reading "Discovery - Explore behaviour using examples" by Gáspár Nagy and Seb Rose. It's the first in a series of books about BDD (Behavior-Driven Development). The next parts are yet to be written/published. Part of the reason to pick up this book was that I'd seen it on Twitter (that alone would not be a sufficient reason of course). The biggest reason was that after delivering a testing and aggregate design workshop, I noticed that my acceptance test skills aren't what they should be. After several years of not working as a developer on a project for a client, I realized again that (a quote from the book):
You can write good software only for problems that you understand.
BDD book 1 - "Discovery" - revolves around this fact of the developer's life. How often did you produce a piece of code based on some vague issue in Jira, only to realize after showing it to stakeholders that almost everything about it was wrong? Often you don't know enough, so you'll mix in some of your own assumptions. And very often, you don't know how the thing you wrote is actually going to be used. In short, you don't know if what you created is adequate. You can write any amount of clean code, with lots of automated tests, and no observable bugs; if the software doesn't fit the intended use, it's useless.
You have to get out of the code, move away from your desk, and talk to the people who want you to build the software. Don't let them give you a requirements document and leave you alone afterwards. Don't lock yourself up with your project manager for a day-long sprint planning. Make sure you get together more often for a quick session to come up with good examples, of what kind of information will go into the system, what rules there are about processing the information, and what the expected outcomes are. Make sure you talk about realistic scenarios, and document all of the decisions you make.
Seems easy, but this, for many of us including myself, is far out of the comfort zone. I'm happy if I can do some coding alone. But eventually, you want clients and users to be happy about what you produce, and this only happens when what you build is useful to them. It should match their way of living, their business processes, their domain expertise.
BDD: not about tools, not about testing
It's my habit to mock development subcultures, like DDD, but also BDD. Even though what they bring to the table is very useful, there are always blanket statements that people will start using, to identify themselves with that subculture.
The process of learning a culture— enculturation— is partly explicit but mostly implicit. The explicit part can be put into books and taught in seminars or classrooms. Most of culture is acquired by a process of absorption— by living and practicing the culture with those who already share it.
West, David. Object Thinking (Developer Reference) (Kindle Locations 244-246). Pearson Education. Kindle Edition.
The same is actually true for myself, quoting David West and all.
#DDDesign blanket statement; can be inserted anywhere in the conversation: "Maybe there's a concept that's missing."— Matthias Noback (@matthiasnoback) April 6, 2018
I was actually anticipating to read BDD subculture's favorite thing to say: "BDD is not about the tools". So I was happy to see it here too:
One typical mistake is to see BDD as a tool-thing. BDD is primarily about collaboration and domain discovery; any “BDD tool” can be only useful in supporting this process. You have to start by investing in collaborative discussions and the creation of a shared vocabulary. Just going after automation (using Cucumber or SpecFlow) does not work.
No hard feelings of course, because this is simply true. I've seen it happen too. PHP's Cucumber is called Behat. Many projects that use Behat end up having many, many scenarios. That may sound like a good thing. Although these scenarios are all written in plain English, which may give the illusion that they are business-oriented, they don't do anything a simple PHPUnit test case couldn't do.
The power of Gherkin (the syntax for these scenarios) lies in being able to capture usage examples, together with business rules. The only way to come up with good examples and to find out the business rules involved, is to collaborate with the people who actually know about them. That's why BDD isn't about the tools. Just by writing test scenarios in your natural language, you won't be doing BDD.
Examples, rules, and scenarios
I've used several words whose meaning may not be self-evident. The way I understood it from the "Discovery" book:
Examples are descriptions of how a user would actually use a specific part of the application. They are concrete; they use meaningful data. They describe different stages ("steps") of the user interacting with the application.
Rules are policies; they describe possible paths, things that are allowed, invariants that should be protected, etc.
Examples are illustrations of those rules.
After you've determined usage examples, meaningful data, and business rules (in a requirements workshop - read more about this in the book), you can start writing scenarios. If you're using Behat or something alike, a scenario has the following template:
Scenario: [description of the rule] Given ... When ... Then ...
The famous Given-When-Then way of writing scenario's reflects the Arrange-Act-Assert setup for unit tests you may already be familiar with. The authors call the act of rewriting examples and rules as scenarios "formulation". The way you formulate a scenario influences the way you can later write code "behind" these steps. That's why the authors write that
Formulation is usually undertaken by a pair, often a developer and a tester.
I think this is an important quote. Often I've heard people say that Behat is not for them, because the stakeholders are not at all interested in the scenarios they write. So why write them? First of all, you need to distinguish between:
- Collecting requirements in the form of examples and rules.
- Writing and automating scenarios.
Activity 1 really needs good collaboration with stakeholders. But activity 2 is something you can do on your own (preferably together, to end up with something better). My advice has always been: if you want to make a culture change, just make your work a good example (no pun intended). The authors agree:
You could try following a BDD approach without business involvement, as a first step – you’ll get all the benefits outlined above and, in time, your business colleagues will come to appreciate the value of expressing the acceptance criteria as plain English scenarios.
The act of formulating scenarios is something you need to do as a team. One developer can do it, but they should be reviewed. There's a lot to it; some scenarios are better than others. Although the book does contain some suggestions about writing good scenarios (e.g. don't illustrate multiple rules in one scenario, write interesting scenarios, not lots of boring ones), the authors announced a second book about the topic of formulation.
If besides writing unit tests for your code units, you also formulate scenarios containing realistic examples describing actual business rules, and then you also execute these scenarios by means of a test automation tool like Behat, you'll end up with the most amazing thing: living documentation (the best reference for this topic is always Cyrille Martraire's book Living documentation). The scenarios document the expected behavior of the application. It will automatically be "living" documentation, since it can never become outdated. If it does, executing the scenarios will simply fail.
Align tasks to scenarios
One "trick" you can already start applying, is to align tasks by scenarios (even if you don't write scenarios!). The opposite would be aligning them by technical implementation detail. Looking back on some of my past projects, I know that we'd been working on it for months, without being able to show even one working, useful scenario to the stakeholders. I remember myself reporting things like "We're still working on a good foundation." (i.e. we were working on the messaging infrastructure, the database design, etc.).
The team will focus on the expected behaviour during the implementation. This can help avoid “gold-plating” or implementing infrastructures that are not needed. Starting from the scenario helps follow an outside-in development approach. You can get feedback about the story implementation earlier. Imagine you have a half-done story, where all the database tables are created, but nothing is visible for the users. Now compare it with a half-done story, where 3 of the 7 scenarios are already implemented end-to-end. The latter can be shown to the product owner to get feedback on what has been implemented so far.
In conclusion - go ahead and read "The BDD Books - Discovery"!