TDD is important to the BDD/Cucumber plan for how information flows through a team. There is no concept of business requirements in BDD (which is risky, but I write about that in my book) so first the functional requirements get worked out recorded in Gherkin-language steps and then the feature gets implemented to enable the test to pass… except it seldom actually works that way.
If it were possible to completely implement the check before starting implementation of the feature in product code, then I can see the allure of the TDD approach: the developer is required to define what the product feature does from the end-user’s (or, customer’s) point of view before implementing it. I guess the idea is that this is a useful approach to managing nerds’ tendency to just implement a feature for him or herself. (Yes, I can be quite the nerd and have been there/done that.)
I can see that TDD-benefit working if the check is a simple verification of some behavior on a very simple interface, e.g., a service call or API, or the first example (called “Multi-Currency Money”) in Kent Beck’s 2003 book “Test-Driven Development By Example.” But in that case, the magnitude of the benefit is almost zero because there is unlikely to be any misunderstanding about intended behavior.
If the benefit of TDD is measured in code complexity and risk by how much it clarifies the end-user’s needs to nerdy devs, but the execution of TDD is limited by that same code complexity and risk, then the potential benefit of TDD is cancelled out by ability to execute.
By that reasoning, TDD looks worthless. TDD practitioners please leap to the defense of their favorite initialism (TDD); if I am missing something important, I need to learn and teach.
The Cucumber book is full of admissions that TDD does not really work, for example:
On page 109, “The step is lying! … it’s passed. We know from our implementation that [it is incomplete].”
On page 129, "The code we've written makes the scenario pass, but the system isn't really of any use yet…"
I would be concerned about TDD making manual test of a feature appear unnecessary to the team. The need for manual test never goes away as I describe here.
A check might need to change, for example if the perf is different from what was expected, GUI race conditions show up, GUI objects don't exist with the expected identifiers, or if the dev finds a better way to implement it as compared to what was expected by the TDD check author.
The QA role might also think that the test-first checks are all that are needed for quality automation, which would create a different kind of quality risk: insufficient quality checks to ensure that functional requirements are always met in the SUT, despite the code churn of product development.
Does TDD with Cucumber actually mean just describing the scenario first in Gherkin steps, with the code-behind to be filled in later? Does it actually mean developing the product feature and an automated verification for it at roughly the same time? In either case, it’s really not TDD in the sense popularized by Beck. In the preface (page IX) of Beck’s 2003 book his first rule of TDD is this: “Write new code only if an automated test has failed,” i.e., the check code must be complete before product code is written.
Beck made a great metaphor: a crank with ratcheted teeth to pull up a large bucket of water. Like the ratchets that ensure the bucket of water does not fall down again, automated checks ensure that product quality is (at least by what the checks measure) not going backward while all the code churn is going on during product development. That has why my work is primarily around developing those checks to be as fast as possible, completely trustworthy and clear as to what the SUT is driven to do and how it’s measured, and complete as practical; it’s about managing quality risk, and keeping the SUT moving forward.
But, from my discussion above, test-first seems neither practical nor valuable. Test (or, more specifically, check) at the same time or soon after some development makes much more sense.
Previous posts in this series:
- Introductory post
- What I like about “The Cucumber Book, Second Edition”
- What I dislike about “The Cucumber Book, Second Edition”: Style issues
- What I dislike about the book: How it relates to software development
- What I like about BDD/Cucumber
- What I dislike about BDD/Cucumber: Promises, promises...
- What I dislike about BDD / Cucumber: Architectural issues
This is the last post in the series about "The Cucumber Book, Second Edition."