An excerpt from the preface of my book.
One important aspect of systems-thinking is that a system is not its components but is defined by the way these interact in a way that creates the behavior.
But the nature of these interactions are very complex – meaning that they can’t be predicted. Unforeseen events & interactions occur. And sometimes small mis-understandings cause huge side effects. This is a reflection that product development is both complex (unknowable in advance) and chaotic (small things can have big effects).
While I believe a deep understanding of complexity can be useful, very little is needed to attend to it. In the same way engineers were quite effective in building magnificent edifices (e.g., the Pyramids) without a full understanding of the science underneath them, it is possible to adjust the behavior of complex systems without understanding the exact results of proposed changes.
We mostly need is to know that 1) our changes may produce unexpected behavior and 2) we are embedded in a system where small errors can cause big changes. This requires quick feedback both about the actions we take and process improvements we try. Both agility of development and improvement of our methods is required.
TDD is different from QA in many respects. Part of this involves the tests we choose to write. A case in point is the specification of public constants. Continue reading “Specifying Constants in TDD”
Flow-thinking is my latest thing. It’s looking at how to achieve value in the quickest way. This is not necessarily going faster – but mostly avoiding delays. I have observed that when I consult with clients I look for the following:
- hand offs (these delay value because they typically cause a degradation in understanding)
- delays in workflow (i.e., waiting for someone)
- interruptions to workflow (often caused by working on too many things)
- delays in feedback – a symptom is when work goes upstream (e.g., dev back to product owners)
- doing less valuable work than what could be worked on
- doing work manually that could be automated
As you minimize these you almost certainly will improve your value delivery. Quality typically goes up as well.
Because TDD is “test” driven development, people tend to think of TDD as “writing tests first.” In fact, TDD is not a testing activity per se. It is the creation of an executable specification prior to the creation of each system element. Unit tests are a very useful by-product of this process.
Because of this point of view, TDD dictates that different tests be written, or written differently than the QA point of view would lead us to do. There are points of overlap, but there are distinct differences, and this means that those new to TDD often miss certain important tests. Continue reading “Commonly Missing Tests in TDD”
Design patterns in software came from the work of the Gang of Four in the mid-1990’s. Similarly, TDD was first promoted around the same time in history as part of eXtreme Programming. Some have suggested that these two points of view stand in opposition to each other, saying
Design patterns are about up-front design, while TDD is about emerging design through the test-first process.
In truth, TDD and design patterns are highly synergistic. Understanding each of them contributes to your understanding of the other. Continue reading “TDD and Design Patterns”
When a test precedes development, it essentially becomes the first “client” for the behavior being developed. This fact is helpful in several ways.
First, the interfaces TDD drives into the system are always client-focused. They are not implementation-focused because at the moment they are created there is no implementation yet. In their seminal book on Design Patterns, the Gang of Four recommended, among other things, that we “design to interfaces.” TDD promotes this in a fundamental way.
Also, the tests themselves provide a glimpse into the qualities of future clients. For example, Continue reading “Tests are Client Number 1”
While many Agilists have been celebrating attempting to adopt Agile as crossing the chasm, it’s been little noticed that we’re on the edge of a new paradigm. While not yet named, it’s been called “FLOW”, “product development flow”, and “business agility”, among others. This paradigm shift goes beyond Lean’s paradigm shift (which Agile has not yet embraced). Essentially, it’s both a different focus on value & a different way of getting there.
The focus is on value to the business (which, of course, is mostly comprised of value to select customers). It also has an organizational instead of team centric. Another difference is a belief that, although, or even because) product development is embedded in the complex system called an organization, it is important to attend to laws and principles of product development. But the biggest shift is that instead of focusing on frameworks to help us, we need to focus directly on the work to be done. Here are the shifts:
- Focus on the system not individuals
- Use science of flow, systems-thinking and lean
- Focus directly on what we’re trying to achieve instead of frameworks Paradigm shifts are shifts in beliefs.
This is not the same as putting flow or Lean into Agile.
When we hear something that we know is wrong we typically ignore it or argue with it. But there is often truth in something we don’t yet understand. One can’t tell at this point of course. It could be wrong. But it could hold some value if we’d explore a little further.
I have found it valuable to ask the question:
“what if this (absurd) statement is true?”
A good way to explore this question is to pretend the statement _is_ true – at least for a little while. This opens the door to many other questions such as “what am I not seeing?” “what am I looking at that is in my way?” “what does this person see that I don’t?” “what are they not looking at that I am looking at?”
You can even (for a limited time) act as if it is true and see what happens. Maybe you’ll learn something. Worst case is you’ll learn you were right (or still think so).
When organizations adopt TDD as their development paradigm, early results can be quite good once the teams get over the initial learning curve. Code quality goes up, defect rate goes down, and the team gains confidence which allows them to be aggressive in pursuing business value.
But there is a negative trend that can emerge as the test suite grows in size over time. Continue reading “TDD “Good” Tests Part 3. There must be no other test that fails for this reason”
When a test fails for a reason other than intended, then upon investigating the cause of that failure the natural assumption will be that it is failing for the reason intended. Thus, the failure will mislead the team into investigating the wrong problem.
Anything that wastes developer time is to be avoided resolutely. Developer time is a highly crucial resource in modern development in that a) you need it to get anything done, and b) you can’t make more of it than you have. There are only so many hours in the day, and only so much time, focus, and energy a given person can devote to a task. Wasting this resource is like burning money in the street. Continue reading “TDD “Good” Tests Part 2. The test must never fail for any other reason”