Effective Scrum and High Quality Code – It Is a Chicken and Egg Relationship
Scrum is simple, but Scrum is Hard. Scrum is so simple that it can be explained in 20 minutes, but so hard that some teams are never effective. Yet other teams produce 3-10 times more business value than they did before. This article will go into one of the main differences between under-performing teams and very successful teams— Code Quality—and its impact on the effectiveness of every Scrum team. You will learn how to present the business case for high quality code, how to facilitate the establishment of a business commitment to high quality code, and how to implement the process of transforming code quality to an enabler rather than a restrainer of the delivery of business value within your organization.
Understanding What Quality Is
Software quality according to Juran
"The word quality has multiple meanings. Two of these meanings dominate the use of the word: 1. Quality consists of those product features which meet the need of customers and thereby provide product satisfaction. 2. Quality consists of freedom from deficiencies. Nevertheless, in a handbook such as this it is convenient to standardize on a short definition of the word quality as "fitness for use"." 
How much quality is enough? It might seem like this is a question like how much of something that you desire, can you afford to buy? When I was a young boy, my mom sent me to the store for an ingredient she needed for a recipe she was working on. I don’t remember what it was she needed, but for some reason she was not able to go, I suspect it had to do with my younger brothers. The store was only 2 blocks away and I was used to walking to school, which was a bit further. She gave me some cash, paper money as I recall and she said that it was more than enough and I understood what she needed. So off I went. Around the corner, down a gentle hill to an arterial street. She had cautioned me about crossing that street and I was careful and easily crossed the street to the neighborhood grocery. I marched in, found the item I was after, noted the price and started to do the math. How much stuff could I get with the pending bonus of change! I really don’t remember what I added to the order, but it took me a while to pick it out! You can imagine what a boy of 8 or 9 would want. Candy, small toys, some pencils, I’ll have to see if mom remembers. I made my purchase and still had a little money left, but took my bag and headed home. Mom could probably have gone upstairs and watched for me out of the bedroom window, but by the time I got back, I had taken too long and she was waiting for me at the front door. I don’t think I really got into big trouble because it was not a lot of money and she had not told me that I couldn’t buy anything! But this event is a part of Claar family lore!
Does your team decide how much to spend on quality by how much budget has been allocated? Or how much time was planned? If so, how does this financial or project decision predict product quality? Is there a correlation? Is this kind of planning effective or valid? Well, that depends. How much quality do we need and can we get it with that time or money?
There are valid assumptions that a product team can make about the importance of quality for a particular solution and problem domain. Software that protects (or endangers) human life would arguably need to be the very highest quality possible. For example, medical devices, systems that conduct and manger inherently dangerous activities, like flying or high-speed rail systems and military systems would all fall into that highest category.
The next step down in a relative quality sense, would be the management and protection of large amounts of money or other valuable goods. Examples here are banks, insurance companies, the stock market and other similar organizations.
At lower levels it starts to become more difficult to differentiate between types of products that need quality but in this next level would be commercial products used to create value, routine transportation of people and products and high commercial value systems used by businesses and families.
In my estimation the fourth tier are non-critical systems that make life easier, provide entertainment and comfort for humans and production animals, systems and production capabilities.
These are generalizations, of course, and every team feels that their product needs to be the best possible. However the reality of the cost of insuring quality often collides with those goals and intentions.
Even though I’m suggesting that human health and life dictate a high quality system, don’t underestimate the force and pressure that comes to bear on the quality of commercial, transportation and entertainment systems with huge levels of revenue and visibility. Think about a major airline that suffers a breakdown in its reservation and ticketing system. No airplane is in danger of crashing because of this downtime, but the entire airline is in danger. Or consider a new video game rolled out to millions of rabid, anxious and cash-rich gamers who have waited for months for this release and as they begin to log in and start playing, the system grinds to a halt.
Software system quality is important and getting more so, every day. More about that later.
Software quality according to Deming
"The problem inherent in attempts to define the quality of a product, almost any product, were stated by the master Walter A. Shewhart. The difficulty in defining quality is to translate future needs of the user into measurable characteristics, so that a product can be designed and turned out to give satisfaction at a price that the user will pay. This is not easy, and as soon as one feels fairly successful in the endeavor, he finds that the needs of the consumer have changed, competitors have moved in, etc."
Software quality generally refers to two related but different concepts in a business context.
· Software functional quality reflects how well it complies with or conforms to a given design, based on functional requirements or specifications. That attribute can also be described as the fitness for purpose of a piece of software or how it compares to competitors in the marketplace as a worthwhile product;
· Software structural quality refers to how it meets non-functional requirements that support the delivery of the functional requirements, such as robustness or maintainability, the degree to which the software was produced correctly.
Functional quality is determined through testing. Functional testing is about asking, “does the solution do the right thing?” “Does the system deliver the business value planned?”
Structural quality is determined through the analysis of the system, its components and source code. The Consortium for IT Software Quality (CISQ) has defined 5 major desirable structural characteristics needed for a piece of software to provide business value: Reliability, Efficiency, Security, Maintainability and (adequate) Size.
The desirable structural characteristics and their associated measurable attributes are shown in this chart from Manuel Barbero.
While the study of these concepts is required for a full, professional understanding of code quality, they do not lend themselves to being used for making the business decisions about how much needs to be spent on quality and/or what impacts poor quality is likely to have on the delivery of business value.
Counting bugs is not a measure of quality!
How do we measure quality? You probably have a system where you track and manage defects in your system that the team has discovered or been encountered. Is this a reliable and actionable measure of system quality? Often development managers track the rate of discovery of defects and attempt to resolve them at a faster rate than they are being discovered. Obviously this requires a commitment to a significant stream of expenditure and commitment of people to keep the bug count under control. However, such a system delivers very little information on the quality of the product or information about the rate of change in quality and the direction. Many studies have shown that the more bugs that your team finds, the more there are to find. If you think it is bad, it is probably worse than you think!
In a lot of organizations, this is just a bug count! From a raw statistical point of view, it is the raw count is perceived as an indication of product quality and justifies the effort to count and eradicate bugs. However, in a large portion of the cases, the open bug count and the rates of discovery and resolution are not a useable measure of product quality. I’m not saying that these efforts are not valuable, but simply that an enterprise cannot make a rational decision on quality from these statistics.
So how does an organization measure quality in a meaningful way? I believe that any assessment of quality has to evaluate the ability of the system to deliver new and different business value in the future than it is currently capable of.
We have to ask the question, “does the solution deliver value to the users and stakeholders?” Do the users get value, accomplish something, go somewhere, create value, save lives or have fun using the system at a reasonable cost or effort?
I’m sure that there are systems that have been maligned, disliked and even hated, yet delivered business value. I’m also absolutely sure that there are many systems that cost more to produce and maintain than they ever delivered in their entire lifetime, in business value. However any system that existed for very long must have delivered more than it cost. Therefore, we can assume an existing system delivers some net positive business value the way it is, and our focus and long-term target should be on how well and how easily can the system deliver new and different business value in the future.
Assessing the System Capacity to Deliver New and Additional Business Value
How well will the system adapt to new and changing requirements? How affordable will maintenance be in a reducing revenue scenario? How easy will it be to port existing functionality to different uses and scenarios on different platforms?
We often talk about “sustainability” from a human perspective. While this is very important, we must also consider solution sustainability. The traditional assumption that existing systems will decay, become more difficult and expensive to maintain and eventually need to be replaced, is just not true. In fact, it must not be true. We must continue to harvest business value from existing systems. The ever-increasing demand on our industry to deliver new and better software-centric systems has reached a stage where more demand is created every day than the capacity to fulfill that demand grows. If we are to meet the new demand, existing systems must continue to deliver business value and they must deliver business value with a reasonable cost for maintenance and the new requirements that will emerge.
When I am asked to take a look at the quality of a system, I focus on these factors:
The first attribute I look at when evaluating a system is viscosity. Is it hard to “move” the system in new and different directions? New, big things are often easier to add, but sometimes even this is difficult and made so because of characteristics of poor quality code. How easy is it to add a reasonably expectable variation? How hard is it to change or add one small feature when the underlying system has poor quality?
For example, the system does something now, like take a common credit card type as payment. How hard is it to add a different credit card type with high quality? It might be much easier to add this new credit card type while ignoring the quality issues. I’m suggesting that if you expect to continue to have the system produce business value, this is not a viable option.
System Viscosity can be described as one of these three types. 
· 'Knock-on viscosity' : a change in the code violates internal constraints in the program, whose resolution may violate further internal constraints.
· 'Repetition viscosity' : a single action within the user’s conceptual model requires many, repetitive device actions.
· 'Scope viscosity' : a change in the size of the input data set requires changes to the program structure itself.
No matter what type, the Viscosity will make it harder to add features now or later. This increases the cost of the solution and lowers the net potential for business value delivered and often prevents the delivery of any business value.
When we add new features to a system, we need to test them. We need to ensure that they do the right thing and do it correctly. My second focus is to look at how hard it is to test the new features. This issue is partially related to the complexity of the new feature, but if the complexity is high, that is all the more reason to pursue higher quality.
The symptom of poor testability is caused by these root causes:
· Unnecessary complexity.
The problems we solve are complex. However, solutions are commonly more complex than they need to be. Practices like combining the steps in a process into a fixed chain or building anticipated features are two examples.
· Unnecessary coupling.
Coupling at the class or object level often results from levels of encapsulation that are too low. The internal values and methods in a system should not be available to any program to use.
· Inappropriate binding of concepts in the solution.
Every problem domain contains many concepts that relate to each other and model the physical world or a process being created. Originally, these concepts were referred to as the “nouns” in the domain, but today many realize that they are more than just people, places and things. They are distinct entities with goals, characteristics and behaviors. When these distinct concepts are bound together in a solution, it becomes very difficult to separate them so that the different concepts can be used in other scenarios.
When these problems exist, it becomes very difficult, time consuming and risky to move the solution to a more testable quality state. These problems impact manual testing by making it harder to create the testing scenarios, creating the need for many more scenarios and increasing the difficulty of running the scenarios repeatedly without errors. Complete testing is impossible and not affordable.
During the time that the last Mars lander was on its way from Earth to Mars, the development team very carefully, manually examined all the code in the landing sequence. We now know that the code had sufficient quality to deliver the intended value, but even after months of review and testing, the team did not know if it was going to be enough, as demonstrated by their worry before landing and exhilaration after the successful landing.
Manual testing is not enough in any non-trivial system because we don’t know how much is enough and we can’t delay the project and spend the money required to accomplish all the testing that would be required in a system with these issues.
The situation with automated testing is just as bad, or worse, when these conditions exist. Unnecessary complexity requires many more paths through the system be tested. Unnecessary coupling requires that code sections that do not have anything to do with the intended goal have to be brought into the testing scenario, exposing the test to unintended code execution and errors, especially in weakly typed platforms. The inappropriate binding of concepts creates situations where some code paths that were not intended are unavoidable at testing and runtime. All of these situations make automated tests harder to create, costlier to build, more difficult to maintain and more time consuming to run.
When the symptoms of unnecessary complexity, unnecessary coupling and inappropriate binding of concepts exist, tests do not get created and when they do exist, have a lower chance they will be run because of the effort and time it takes to run them. When tests do not exist, or are not run, the business cannot be sure that the system delivers the business value planned.
The Ultimate Measure of Quality – The Pace of Business Value Delivery
The Value Stream Map – a Lean tool.
If the goal is truly fast paced delivery of business value, then that is the ultimate measure of quality. In other words, the enterprise should recognize the delivery of business value as the primary goal and use that goal to discover and mitigate or remove issues that impede the pace of business value delivery.
One of the tools used by the Lean community is the value stream map. A value stream map is a graphical analysis of a system that is used to identify the process used to create business value and to identify potential process improvements to increase the pace.
The relationship between actual, value producing work and the total time it takes to do that work is the critical focus. Here is an example where the manufacturing process takes 15 minutes over 68 calendar days. 
A few years ago, I directed an assessment of the processes at a large company with the goal of identifying steps to improve the delivery of business value. One of the tools we used was a value stream map. The business provided us with a dozen or so people from a few different departments for the exercise. The first step was to identify a feature that had been recently delivered. One was chosen that had taken about 8 months to complete. Here is the analysis. The blue box obscures the actual requirement to respect the confidentiality of the customer.
The goal is to identify where the work is slowed and to create a measurement of relative process efficiency that can be used to gauge steps aimed at increasing the throughput of business value. The employees knew that it took 8 months to get the feature through the process. However the actual value-producing effort was so small and the process to get the value so recursive, it was going to be a major mathematical process to develop the relative process efficiency. I suggested that we just round it off to 0%! They agreed.
Obviously there was a problem. It would be very easy to identify areas where waste was being created and attack those. As the enterprise digs into these issues they are likely to discover root-cause problems with processes, code quality, architectural issues, scarce skills, bad requirements and other issues. However the measure of quality, from a business value delivery point of view is clear. The production system is clogged. Almost nothing is getting though the system.
The Business Case for Quality
Strategic vs. Tactical Approach to Business Value Delivery
The business case for quality is a case for business value. That should be pretty obvious. Most technical projects undertaken to deliver business value have strategic enterprise goals. Most major projects or departments to manage technical systems are driven by goals like revenue increases, new markets, cost reduction through efficiency gains and the like.
However, because of the organizational disconnect that exists between these strategic motives and the technical execution of the effort to achieve the goals, tactical decisions are often made without a clear understanding of the impact of those decisions on the strategic situation.
No enterprise would make the conscious decision to deliver a product that is so far off the mark that the customers are disappointed and take actions that damage the enterprise. Yet decisions are made every year to ship products that don’t meet the needs of the user and/or have quality that is so poor that new requirements are disproportionately expensive.
Tactical decisions relating to the architecture, platform, algorithms and timeline must reflect the strategic enterprise goals. To do this the enterprise must be clear on strategic goals. One way to achieve this is through Enterprise Agility. In my article “Software Development Process Improvement for Enterprise Sustainability, Why Scrum, Agile and Lean?”  I discuss the proper focus for Enterprise Agility.
1. The delivery of business value quickly.
This is the main point of doing the project and maintaining the team. Delivering the value late or slowly reduces the ROI and may undermine the business and the value of the team.
2. Get quick feedback to validate the course and the solution.
Projects that are successful depend heavily on feedback to insure that the solution really meets the need. Delivering the wrong solution or a poor solution impacts ROI.
3. Deliver the business value in a repeatable and sustainable manner.
If the organization has decided to establish a development team, it expects to have repeatable, sustainable delivery of business value that delivers ROI. If the Pony Express had overworked and abused the horses, its business model would have been impractical.
4. Deliver software solutions that add value now and do not slow down the delivery of business value in the future.
Maintaining this focus will lead the enterprise to a change in how it addresses requirements. Tactically speaking, large requirements with long lead-times and slow feedback make it impossible for the enterprise to be Agile.
Strategic Enterprise Goals need to drive tactical decisions at the project/product level and below. Tactical actions to short cut quality may seem to be the right thing to do for the current situation, but unless remedied quickly will actually impact the delivery of solutions that meet strategic goals in the future.
Removing Poor Quality as an Impediment to the Delivery of Business Value
The first step at the Strategic level is recognizing that poor quality is an impediment. In Agile terms, an impediment is any situation that slows the pace of delivery of business value or raises the cost of delivering business value.
Poor quality will slow the delivery of business value and increase the cost of maintaining the flow of existing business value. The first and most obvious reason this is true is the waste in the form of the rework that flows from defects in requirements or in code. Excessive and unnecessary complexity leads to viscosity and brittleness slowing and raising the cost of new value creation and existing value maintenance. Untestable code exposes the enterprise to the waste of the rework that stems from building the wrong thing or solutions that just don’t work.
When I have the opportunity to speak to leaders about their role in Scrum, one of the major points I make is that as a leadership team, they must “walk the walk” when it comes to supporting the products and teams. The most obvious issue is the active, positive and decisive response to mitigate or remove impediments. Sometimes it is a hardware or infrastructure issue. Rather than adding the new build server to the next year’s capital budget, funds are allocated to bring the new server online as soon as possible.
Poor quality is probably the biggest impediment for most organizations and in a lot of cases, it is the easiest to deal with. It starts with an open and sincere commitment to quality from the leadership. Just as important is the adoption and support for the Lean Principle of “Build Quality In”.
Enterprise Commitment to Quality
Building quality in also means an enterprise commitment to the highest quality possible. This starts at the top. Leadership must support the pursuit of quality within the context of delivering more business value faster. Leadership must openly support the development of an Enterprise Backlog so that common business capabilities are built once rather than several times. Leadership must understand and promote smaller, more frequent releases to deliver more business value over time.
The enterprise must commit to providing the development teams with everything they need to do high-value releases with sustainable quality.
The Lean Principle “Build Quality In”
The primary way that enterprises can remove poor quality as an impediment is by adopting the Lean Principle “Build Quality In”. This principle is critical to Enterprise Agility. What it means is that the only way to have quality, is to make it part of the product. Quality rises to the level of a required feature. Without this built-in quality, all other features loose significant value.
The first axiom of the “Build Quality In” Principle is that you can’t test quality in. We’ve already discussed the value of testing, so I’m not saying don’t test. Rather many have found that testing does not indicate or ensure quality. I’m not saying that if you find a defect that is preventing the delivery of business value and you fix it, that you have not done a good thing. However, you may have unwittingly signed your customer up to do the testing and you have probably made this fix at relatively expensive point in the life of your product.
Attempting to test quality in often requires the allocation of schedule time, humans to do the testing and time and effort to fix what is found. No one wants to estimate this phase of a project and it has been statistically shown that the more defects you find, the more there are to find! So the longer it takes, the more time and effort you have remaining!
Deliver More Business Value Faster
This step is a bit tricky and should only be worked on when the commitment to quality and the adoption of “build quality in” are well established.
Leadership should support, even demand that product teams build less, build simpler and deliver faster. Well trained and focused teams will recognize this approach as being a core Scrum principle and the leadership requirement to do so should be underscored with an open recognition and support for building less, faster.
This is tricky because it is very easy to be misinterpreted as the traditional demand to deliver features on a specific date. Leadership should be very clear that the identification of smaller, minimal releases delivered at a faster pace is the goal.
One way to do this is to have the product management team suggest a release date that has significantly shorter lead time than the organization has been using. Then leadership should underscore the quality and business value goals for the release.
Build Only Against Acceptance Tests
Lastly, leadership must insist on an Acceptance Test Driven approach. This top-down testing does more to clarify requirements than any other practice. Leadership should also make it very clear that no code, features, modules or components will be delivered in the release that do not contribute directly to these goal driven acceptance tests.
The Tactical Practices for the Lean Principle “Build Quality In”
Step One – Don’t Make Any More Technical Debt (Unintentionally)
I have heard my good buddy Dan Rawsthorne tell teams “don’t be stupid on purpose!” He is talking about not having the guts to do the right thing. Technical Debt is created when the team creates an implementation that is not the highest quality that is possible. When the implantation is created, some extra burden of maintenance or cost to add other business value is also created.
We are talking about explicit decisions. We may not know better, but that is a different problem. Not knowing better will also create technical debt, but we can’t do what we don’t know to do.
Cunningham offers some examples of this debt. (Wiki links removed for readability, see the source.)
· It's too late in the Life Cycle to upgrade to the new release of the compiler. We'll do it next time around.
· We're not completely conforming to the User Interface guidelines. We'll get to it next time.
· We don't have time to uncruft (refactor, see Refactor Mercilessly) the hyper-widget code. Punt until next time.
He also offers these clarifications:
· Technical Debt includes those internal things that you choose not to do now, but which will impede future development if left undone. This includes deferred refactoring.
· Technical Debt doesn't include deferred functionality, except possibly in edge cases where delivered functionality is "good enough" for the customer, but doesn't satisfy some standard (e.g., a UI element that isn't fully compliant with some UI standard).
Ward offers this recommendation:
· Make the debt visible. Keep an explicit Technical Debt List. Group deferred tasks into workable units, note the consequences of leaving each unit unattended. Keep the list visible. Make sure that Marketing knows that the list exists, and repeat the mantra "If we don't schedule time to pay off Technical Debt, you might not get all of the new features that you want."
So the organization must follow Dan’s advice. Don’t make any more technical debt on purpose! The weight of existing technical issues is probably already slowing your delivery of business value down. The only way to dig out of the hole is to not make it any deeper!
Understand Acceptance Criteria
When new pilots are in training one of the most unnatural things to learn is the repeating back of instructions to the control tower or Air Traffic Control. Sometimes these instructions are pretty complicated and the pilot has to write the instructions down and read them back. Obviously the reason this is so critical is that the controller needs you to carry out his instructions and the first step in this is that you correctly heard these instructions. But that is not all there is to it. The pilot must understand these instructions to carry them out and maintain the safety of flight operations. After the pilot hears, writes and repeats then the training tells the pilot to check his understanding of the instructions. If they are not understood, the pilot must ask for a clarification and the whole process starts over again. In this domain, the pilot generally understands the instructions because their preparation and training make most of these instructions routine.
As developers, when we get our instructions from ATC, that is our requirements, they are often written rather than spoken. How well we understand those instructions depends on a number of factors, starting with how well they were understood by the person writing them and their skill in putting them into words. However a document does not have the built-in feedback loop that is required of pilots! It is also very common for us to understand every word in the document, yet not have a clue what they are talking about or even worse think we understand perfectly when we really don’t have a clue.
How could we create a feedback loop to increase the chance that we understand what is needed and build the right thing?
· Assume we understand the requirements and how to write the code and then depend on a Scrum feedback to check our understanding.
· Assuming we know, then ask a few questions to validate our assumption.
· State the requirements back using different words in a different document.
Each of these approaches involves some presumed understanding and interpretation by the team. Any of these approaches will work. However there is some built-in delay in the validation of our understanding. And the risk that we won’t fully comprehend the response would start the cycle over again. The waste could be huge as the team may have started coding with an incorrect or incomplete understanding of the requirements.
Requirements by Example
If we are to shorten the feedback loop and reduce the rework from building the wrong thing, we need a way to quickly state back the requirements in such a way that it is clear to the Product Owner  that the team understands the requirement. There are several names for this practice, but I like “Requirements by Example”. 
The team, in the process of the analysis and planning for a new feature, would solicit from the Product Owner some specific, tangible examples of the result of the new feature working correctly. For a very simple example, imagine that we are building a calculator that can add integers. Several examples might be like this:
1 plus 1 equals 2
1 plus 4 equals 5
34 plus 21 equals 55
Obviously, real world problems would be much more complex. However in the vast majority of cases, requirements by example does work, even if the example is a more complex process perhaps requiring multiple steps.
With this validation in hand, the team can proceed to create the code that creates the results desired and demonstrated in the examples.
Moving Testing Forward
When we talk about code quality, there is an enormous body of work, studies, opinions and debates on what quality is or is not. As software professionals, we could probably spend a couple of hours each work day for the rest of our career learning about quality. However, while this is valuable from an academic point of view, it probably would not help you and your team deliver more business value faster. Steve McConnell and others offer some clear, fundamental and generally agreed upon first principles of software development.
· Redundancy makes software more difficult to maintain and can cause bugs that are hard to find.
· Code that we don’t understand is code that is, at best, more difficult to maintain and extend.
· Concepts that are intertwined make code hard to understand and even harder to maintain and extend.
· Concepts that are hard to find make it more difficult to maintain and can cause redundancy.
· Objects that do more than one thing are difficult to understand and maintain.
· Software that is not testable will be difficult (or impossible) to maintain.
Low Redundancy, Understandability, Loose (Intentional) Coupling and High Cohesion are widely accepted as first principles of software development.
Yet the one that stands out for me is Testability. Redundancy means that teams run the risk of missing duplications when testing and/or have to create context specific tests. Code that is not understandable is hard or impossible to test. Code that is needlessly coupled to other components is hard to test. Components that do more than one thing expose the developer/tester to the unintended consequences of low cohesion. Architectural or component changes often break seemingly unrelated tests.
Testable Code is Quality Code
Therefore, because quality cannot be tested in, to achieve true, maintainable quality that enables the delivery of business value in the presence of unknown and changing requirements, testing must be moved forward in the project.
How that is done is an interesting discussion. To get there, let’s talk about what kind of defects are found in software systems. I think that there are two basic kinds of defects.
The first one is just human error. The wrong variable used, an incorrect algorithm, a typo, or just a mistake. This kind of defect generally impacts Structural quality. The system does not operate correctly. The answer returned is wrong. The module does not communicate with other modules. The system does not compile.
The other relates to incorrect, poorly understood and changing requirements. These defects are generally Functional in nature. This is not an absolute fact because bad requirements can clearly create Structural issues. The system does the wrong thing. The customer need is not adequately met. The system does not solve the most important problem. This kind of error is often discovered and the developer says something like “Oh, that’s what you wanted!”.
What we are talking about is a fundamental shift in the approach to quality, away from trying to find defects to preventing defects.
Using a QA process focused on testing after code is complete has several problems. First is the problem of estimation of the testing phase. More often than not, this is a lose-lose situation. If the estimate is too high, costs are higher and delivery of business value is delayed. If the estimate is too low, there is less confidence that testing will be sufficient and the ship date may need to be pushed out. The other big problem is that in this type of QA process, it has been shown that the more defects you find, the more there are yet to be discovered. Attempting to find defects is inherently wasteful.
Tom and Mary Poppendieck state it this way.
The job of tests, and the people that develop and run tests, is to prevent defects, not to find them. A quality assurance organization should champion processes which build quality into code from the start, rather than test quality in later.
This is not to say that verification is unnecessary. Final verification is a good idea; it’s just that finding defects should be the exception, not the rule, during verification.
If verification routinely triggers test-and-fix cycles, then the development process itself is defective.
Moving testing forward is one of the ways teams can prevent defects.
Top-Down Testing with Agile Acceptance Test Driven Development
Preventing Functional defects needs to come first. Starting with the results of the Requirements by Example process, the next step is to persist these examples and turn them into an automated test.
There are a number of tools that support this technique including FIT, Fitnesse, Concodian, Robot Framework, easyb and Cucumber.
Andrew Binstock explains the advantages in his Dr.Dobb’s post.
Acceptance tests have several key advantages over lower-level tests:
· As a design framework prior to coding, they focus the developer on the user's needs. This is an important benefit. It is much easier to design functions correctly, when you can see them holistically, rather than the bottoms-up approach of TDD where the focus is on tiny steps developed within the scope of a single function.
· The developer validates the code at the level of the user experience. If the previous benefit was important, this one is crucial. It is entirely possible to write software that enjoys 100% code coverage, where every unit tests passes, but whose functionality is still broken. Even if the functionality is correct, the software still might not do what the user requested. In counterpoint, if the code is defined by acceptance tests, it is no longer possible to pass all the test and not work or not do what the user requested. Passing all acceptance tests (presuming they’re correctly written) guarantees satisfaction with user needs and validates the software.
· Acceptance tests document the software. This last point gets at what is one of the most pervasive misconceptions about unit tests: that they document the code. This is a canard that keeps being tossed about as a good reason for writing unit tests. It is, in a word, nonsense. If you’re looking at unit tests as documentation for the code, something upstream is seriously broken.
The other big difference that I notice when teams use AATDD, is that it creates a fundamentally different architecture that is testable by design and minimizes the number of paths through the system. When developers have less focused goals, with lower fidelity requirements, they have learned (the hard way) that they need to build more than they are actually given the requirements for. They attempt to anticipate how the feature will be used and build in support for that undocumented need. This obviously makes the solution more complex. Paths through the system are created that need to be tested. This is one of the issues that makes testing after coding so hard to estimate.
When the development team is given specific top down acceptance test criteria and instructed to only write code to make those tests pass, the situation is much different. No anticipation is required by the development team. No other alternate paths are created. And, as Binstock states, 100% code coverage just falls off the truck! Testable code is quality code.
Bottom-Up Testing with Unit Test Driven Development
Another fundamental issue is Structural quality. While this kind of problem can come from a requirements issue, they are more commonly created by human error. These errors are in the code itself. Here again, moving testing forward leverages a tremendous advantage.
Kent Beck is given credit for if not inventing UTDD, at least the formal codification of the process. Bob Martin describes TDD in three rules.
1. You are not allowed to write any production code unless it is to make a failing unit test pass.
2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
This system results in better code. More importantly, this results in a safety net of unit tests that take the fear out of change. Unit tests allow us to move forward with the confidence that we have not broken anything else in our effort to add new functionality. These unit tests run automatically. At any time, any developer can run the tests and evaluate the health and quality of the system.
This is real work, to be sure. However UTDD pays off twice, at least! The first payoff comes when the developer, having written a failing unit test, writes a little code and gets the test to pass. It is a little step, but it creates confidence. It is like taking a little sip of water on a long walk on a sunny day. It just feels good and gives the developer the momentum to go to the next little test.
The second payoff comes when some other developer (or the same developer) makes some change that breaks the code and causes the test to fail. That is the safety net in operation!
Some may protest that the team will be writing more tests than code. My answer to that is “So, what is the problem?” If you are writing code that you know works, because the tests passed, there is much less rework. Some estimates place rework as 30%-40% of the work in a project. James W. Grenning says it this way:
“Another day without Test-Driven Development means more time wasted chasing bugs and watching your code deteriorate... TDD helps you prevent defects and build software with a long useful life.”
Without Unit Tests you have what Michael Feathers refers to as “legacy code,” code that is untested and probably untestable without some significantly risky changes. If your system is “legacy code,” there is no better place to start than with Feather’s book “Working Effectively with Legacy Code.”
Testable Code is Quality Code.
Peer Review of Work in Progress
- Increased discipline. Pairing partners are more likely to "do the right thing" and are less likely to take long breaks. One unexpected result: The Extreme Programming Diet
- Better code. Pairing partners are less likely to go down Gopher Holes and Blind Alleys and tend to come up with higher quality designs.
- Resilient flow. Pairing leads to a different kind of Mental State Called Flow than programming alone, but it does lead to flow. Pairing flow happens more quickly: one programmer asks the other, "What were we working on?" Pairing flow is also more resilient to interruptions: one programmer deals with the interruption while the other keeps working.
- Improved morale. Pair programming, done well, is much more enjoyable than programming alone, done well. (On the other hand, pair programming done poorly is much less enjoyable than programming alone done poorly.)
- Collective code ownership. When everyone on a project is Pair Programming, and pairs rotate frequently, everybody gains a working knowledge of the entire codebase.
- Mentoring. Everyone, even junior programmers, has knowledge that others don't. Pair programming is a painless way of spreading that knowledge.
- Team cohesion. People get to know each other more quickly when pair programming. Pair programming may encourage team jelling.
- Fewer interruptions. People are more reluctant to interrupt a pair than they are to interrupt someone working alone.
Several of the sources quoted in this article talk about the importance of the practice of Code Review. There are lots of ways to do this, but in my experience, the best way is Continuous Code Review otherwise known as Pair Programming. Cunningham lists the advantages (wiki links removed):
The Extreme Programming community has a term called “YAGNI” or “You Ain’t Going To Need It”. What they mean is that a team should not build anything that is not required right now. This applies to design too. While some upfront design is required, too much results in Structural problems when the designer attempts to analyze requirements too early and develop an architecture for a feature that is not well understood yet.
According to Scott Bain, designs should emerge.
Designing for Change
Change will happen, but some is more likely than others. The Poppendiecks talk about designing for change that can be reasonably expected from a customer or business point of view. Martin talks about leaving the code base cleaner every time you make a change.
We must create the path for reasonable change. The book The Pragmatic Programmer talks about the concept of “tracer bullets” in code. If you are writing a class that you know will be updated as a better solution is identified, create the abstract class and the class factory now, so you are ready for the change. When I get to write code, (not very often these days), I probably write too many abstract classes. I once had a conversation with Jim Newkirk, originator of the first unit testing framework for .NET, about when he felt that the abstract and supporting code structures should be created. Jim says that because of that overhead, it is better to wait until the second instance is really required.
So obviously even the experts don’t agree. However, there is a middle ground. What if, in object oriented code, today’s implementation would provide a doorway to a more robust solution, without changing or breaking existing clients?
Simply stated, if you encapsulate (hide) the constructor with the goal of separating use from construction of an OO object, you can do just that.
The Ongoing Improvement and Quality Progress
Scrum is, by definition, an empirical process. That is, it has built-in process steps that the team uses to examine the product and the process to look for ways to improve.
If quality is truly a feature of the product, the Scrum Review Meeting should demonstrate quality, good or bad. The demonstration of the stories built in the sprint should include the acceptance criteria, acceptance tests and if understandable and relevant to the stakeholders, the unit test goals. The demo should be crisp with no fumbling around to demonstrate the feature and if it is not so the Product Owner should not accept the story.
Sometimes things will break. We are imperfect beings. However, what we do when things break says a lot about our commitment to quality. Step one is to write a failing test (acceptance or unit depending on perspective needed) to demonstrate the defect. Step two is to use root cause analysis to uncover the reason that defect exists. Step three is fix the defect in such a way as the root cause is at least mitigated, if not removed.
The “R” Word (shhhh… We are going to do some Refactoring!). Often times when a team tell the Product Owner that they want to do some refactoring, there is a big fight about wasted time and no new features. Refactoring is improving the structure of code without changing the functionality. There has been an ongoing debate about this recently, with most Agile purists coming down on the side of more refactoring for refactoring’s sake. I tend to be more pragmatic than that. Here is my decision tree about refactoring.
If we implement the change without refactoring will the code be cleaner than when we started?
Yes – Implement without refactoring
No – Refactor to be able to make the change and have the code be cleaner than when we started.
Are the modules to be changed for the story supported by an adequate set of unit tests to protect the system from unintended defects?
Yes – Use TDD to add the new story.
No - Refactor just enough to introduce a seam for unit testing (see Feathers).
Problems and Pitfalls
In most business environments, the process to develop new business value with software includes some type of estimation for planning purposes. If these estimates are significantly too high or too low, quality can be at risk.
If estimates are too small, the team will try to provide all the functionality asked for and in the process take short-cuts, abandon the test-first approach, introduce redundancy and otherwise compromise on quality.
When estimates are too large, the impact is very similar, but for different reasons. The most common I have witnessed is the “we have lots of time” syndrome. It often leads to over design and excessive up-front architecture. Then with too much design and significant time wasted, the too small issues are encountered.
Teams need to understand the requirements well enough to deliver the business value agreed to in Sprint Planning consistently. This requires more than good sizing. The team needs to understand the who, where, what and why of the requirement to deliver the right solution. This understanding is impossible if the work items being developed are too large. To deliver the right solution predictably, the teams need to learn how to size their work from the experience of doing the work. The practices of User Stories, Acceptance Testing and Story Point sizing generally will help teams learn to size well enough to avoid quality impacts in 3-4 sprints.
The Delivery of Large, Complex Requirements to the Team
In a traditional approach, significant effort is expended to break the requirements down and plan the work. This “specification” is delivered to the team in a single package. Very little effort is put into prioritization or expressing the motivations for the requirements.
When this large package of work is developed by the team, it is very natural, almost unavoidable that the various requirements are bound together in the solution. A Scrum team given small, discrete and understood requirements are much more likely to build decoupled solutions. This makes it easier to test and reuse the modules.
Time pressure is a significant issue only when the organization has not adopted the Build Quality In principle. Time pressure is exerted when a command and control approach is used rather than one that works to maximize the delivery of business value.
Reducing Cost vs. Increasing Throughput
Companies get into financial trouble. Sometimes it is self-induced and sometimes it is due to external forces. In either case leaders need to make tough decisions that impact the very existence of the organization. The common reaction is to cut costs. While I am not saying that reducing labor expense to cut costs is ineffective, it seldom impacts the core issue. In fact these kinds of cuts often make the problem worse due to delayed delivery of business value and the resulting revenue slowdown.
An organization can improve the situation by looking at the waste in the production system and, rather than cutting cost, reduce waste and increase throughput. Using the principles and practices of Scrum, organizations can easily reduce costs through waste reduction and increasing stream of business value delivery.
What Comes First – Effective Scrum or High Quality Code?
Creating an enterprise plan
In their book Lean Thinking, Womack and Jones propose that the goal of a product development organization should be an interdependent process that creates business value with Speed, Quality and Low Cost.
Each of these three attributes is dependent on the others. Without Quality, you can’t have Low Cost. Without Quality you can’t have Speed. Scrum teaches us that without Speed, we can’t have Quality.
Jeff Sutherland writes about experiencing 200% to 400% increases in productivity using Scrum. If that translates to revenue gains of proportional size, that would be reducing relative cost by 50% to 75%, with a healthier company and happier customers!
What comes first Effective Scrum or Code Quality? I submit that you can’t have Effective Scrum without Code Quality. There are other, valid approaches to Code Quality, but they don’t deliver the business changing impacts of Scrum.
Getting started is easy. Leadership needs to commit to quality, by adopting the approaches I have outlined.
The next steps require some commitment. The biggest hurdle is not accepting the status quo. It is very difficult to change long-entrenched habits. Most organizations need an Enterprise Coach. A trusted Coach can help the organization identify waste, address training needs and propose process improvements.
Most developers that I have trained over the last couple of decades have some familiarity with the principles and practices I am proposing. However, time and circumstance have dulled their view of the benefits of quality. The people who self-select to work in our industry want to do a good job. Their physiological makeup puts quality high on their work goals and they feel good about doing their job well. It is this nature that has made it easy for enterprises to use command and control, mechanistic ways of managing work to modify the behavior of these people resulting in lower quality and lower productivity than is possible by approaches that recognize their strengths and capabilities.
I have found that correcting the impact of traditional approaches requires leadership support and a team reset on code quality and engineering practices.
We feel that the Scrum Alliance’s Certified Scrum Developer program is a great place to start. The program contains 5 days of training that can be configured in different ways, but normally is done with a 2-day Certified ScrumMaster class and a 3-day Engineering Practices class. Please see our web site for more details.
Rod Claar, CST
Effective Agile Development LLC
 J.M. Juran, "Juran's Quality Control Handbook", McGraw-Hill, 1988.
 W. E. Deming, "Out of the crisis: quality, productivity and competitive position". Cambridge University Press, 1988.
 Implementing Lean Software Development: From Concept to Cash, by Mary and Tom Poppendieck. Addison-Wesley. 2006
 Test Driven Development for Embedded C – James W. Grenning
 Emergent Design: The Evolutionary Nature of Professional Software Development - Scott Bain.
 The Pragmatic Programmer – Hunt and Thomas
 Perspectives of Use vs. Creation in Object Oriented Design – Scott Bain