1. specification - Define problem domain we'd like to solve.
2. feedback - Run test and see if the code works.
3. regression - Once it works, it should continue to work, so we run all testcases again to make things still work.
When I got my first gig as a junior software engineer in the 90's, I also did QA works that involves coming up with test cases according to the specification, running the tes tcases to get feedbacks, and re-running the same test cases. When I reported bugs, the test cases reflect an extra aspect:
4. granularity - When things go wrong, what went wrong? We'd like to get more information when tests failed.
As far as I can see, there are two pain points in software development with respect to testing:
- Discover problems late in the game, and
- Not being agile enough for changes/fixes.
Discovery problems late in the process is expensive because cost of change goes up as time moves on. To lower such cost, we want good communication between people in the program domain (stakeholders who have problems) and people in the solution domain (programmers who implement solutions) to have less problems. For the problems, we'd like to be more agile in fixing the problems in the software. For this, we need to make code cleaner by applying refactoring.
Good habits introduced and emphasized by BDD are:
1. Working outside-in
Define behavior we want before we implement that behavior. Talk to domain experts first and code second. Starting from a business or organisational goal, having the requirement challenged, working from business-level to the code-level testing. It’s much cheaper to understand the spec out before you write the code.
2. Using examples to clarify requirements
In order to <why>
As a <persona>
I want to <what>
As a <type of user>, I want <some goal> so that <some reason>
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
Use a common language between stakeholders and programmers so the same thing is called using same right word. Emphasis on collaboration, and the use of business-readable, executable specifications. When everyone is involved in writing documentation that describes what the system should do, they all get a chance to learn the language of the domain together.
- Both include unit tests, acceptance tests, functional tests, integration tests, etc.
- BDD builds upon TDD by formalizing the good habits of the best TDD practitioners. - The Cucumber Book, 2011
- BDD focuses on tests that will not break artificially because of the change of implementation.