- Don't write unit tests, write low-level specifications
- Favor outside-in development
- Learned about Spock framework
- There is a difference between a story and a feature
I used RSpect before but without a clear understanding of BDD, so I wrote unit tests (test scripts) rather than low-level specifications. The book explains why BDD is important along with details steps and examples. BDD is when we write behavior and specification that then drive the software. One of the key goals of BDD is to ensure that everyone has a clear understanding of what the project is trying to deliver, and of the underlying business objective of the problem. BDD is TDD but with better guidelines or even total new approach to developing. This is why wording and semantics are important: the tests need to clearly explains the business behavior they're demonstrating. It encourages people to write tests in terms of the expectations of the program's behavior in a given set of circumstances.
When writing user stories we were told to use this template:
As a <stakeholder> I want <something> so that I can <achieve some business goal>.
Once you have a story, then you have to explore the details by asking the users and other stakeholders for concrete examples.
In BDD the following notation is often used to express examples:
Given <a context>: describes the preconditions for the scenario and prepare the test environment
When <something happens>: describes the action under the test.
Then <you expect some outcome>
Story: Returns go to stock
In order to keep track of stock
As a store owner
I want to add items back to stock when they're returned
Scenario 1: Refunded items should be returned to stock
Given a customer previously bought a black sweater from me
And I currently have three black sweaters left in stock
When he returns the sweater for a refund
Then I should have four black sweaters in stock
Scenario 2: Replaced items should be returned to stock
Given that a customer buys a blue garment
And I have two blue garments in stock
And three black garments in stock.
When he returns the garment for a replacement in black,
Then I should have three blue garments in stock
And two black garments in stock
As the book Specification by Example mentioned, instead of waiting for specifications to be expressed precisely for the first time in the implementation, successful teams illustrate specifications using examples. The team works with the business user or domain experts to identify key examples that describes the functionality. During this process, developers and testers often suggest additional examples that illustrate the edge cases or address areas of the system that are particular problematic. This flushes out functional gaps and inconsistencies and ensure that everyone involved has a share understanding of what needs to be delivered, avoid rework that results from misinterpretation and translation.
Besides understanding the difference of unit tests and specifications, the book also talks about the difference of features vs. user stores. They are NOT the same. A feature is a functionality that you deliver to the end users or to the other stakeholders to support a capability that they need in order to achieve their business goals. A user story is a planning tool that helps you flesh out details of what you need to deliver for a particular feature. You can have features without having stories. Is a matter of fact, a good practice is to summarize the "Given When" sections of the scenario in the title and avoid including any expected outcomes. Because scenarios are based on real business examples, the context and events are usually stable, but the expected outcome may change as the organization changes and evolves the way it does business.
Besides the language syntax, I discovered the Spock framework. It lets you write concise and descriptive tests with less boiler plate code than would be needed using java. The syntax encourages people to write tests in terms of your expectations of the program's behaviors in a given set of circumstances.
While I was reading this book, two quotes came to my head:
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live - M. Goldin.
Programs must be written for people to read, and only incidentally for machines to execute - Adbson and Sussman.
The other insightful thing that I learned is that BDD favors an outside-in development approach. Which they include:
- Start with a high-level acceptance criterion that you want to implement
- Automate the acceptance criterion as pending scenarios, breaking the acceptance criterion into smaller steps
- Implement the acceptance criterion step definition, imagining the code you'd like to have to make each step work
- Use these step definition to flesh out unit tests that specify how the application code will behave
- Implement the application code, and refactor as required
There are many benefits of outside-in development, but the principle motivations are summarized here:
- Outside-in code focuses on business value
- Outside-in code encourages well-designed, easy to understand code
- Outside-in code avoid waste
As I mentioned, I enjoy the book and I found it very insightful. Some (if not all) the ideas of the book has been around for decades. I believe that this book is great for an architect, programmer, testers, project manager, product owner, and scrum masters.