Managing Technical Debt And Defects Within The Scrum Framework
Understanding Technical Debt
Technical debt refers to the implied cost of additional rework caused by choosing an easy software solution now instead of using a better approach that would take longer. It is a design or technical infrastructure issue that is expedient in the short term but sets up a technical context that can make future changes more costly or impossible. Common sources of technical debt include not following best practices, taking shortcuts to speed up development, deferring needed refactoring, and choosing quick solutions over more robust ones.
As teams race to implement features, shortcuts build up as technical debt. If left unaddressed, technical debt accumulates until development velocity slows to a crawl, defects multiply, and the system architecture begins to crumble. Tracking, paying down, and avoiding future technical debt is key for rapid, iterative delivery.
Common Sources of Technical Debt
- Duplicate code and solutions that should be refactored into shared libraries
- Weak code structure that should be reorganized into modules/components
- Poor naming conventions and comments that cause confusion
- Outdated 3rd party libraries with vulnerabilities
- Lack of test automation and code quality practices
- Hardcoded configurations and magic numbers vs externalized constants
- Workarounds to postpone needed design changes
Impact of Accumulating Technical Debt
Living with technical debt causes quality, velocity and morale to steadily deteriorate:
- Increasing number of defects and support issues
- Rework and “code archaeology” overload
- Unable to adapt system to new requirements
- Developers waste time firefighting
- End user frustration grows
Like monetary debt, technical debt incurs interest payments in the form of reduced productivity as complexity and entropy increases. As teams struggle to build new features on top of messy, rigid code, they pay down principal but interest keeps capitalizing. Technical debt should be carefully monitored and strategically repaid to limit its compounding interest payments.
Handling Technical Debt in Scrum
Scrum teams build software iteratively and incrementally, making fast feedback possible. This allows them to compare the cost of doing things “right” vs tolerating technical debt and paying back more later. Technical debt must be managed proactively and paid back frequently to sustain product development speed.
Making Technical Debt Visible
Teams must first stop tolerating bad practices that increase technical debt before they can manage it effectively. Define “definition of done” checklists and engineering practices to prevent accumulation of unintentional debt. Enable developers to flag intentional shortcuts and debts for later repayment. Capture the estimated cost of addressing debts to quantify the liability for planning.
Planning and Prioritizing Tech Debt Repayment
Product owners must allocate sprint capacity for repaying prioritized technical debt items along with new feature work. Rank debts based on severity, risk, interest cost, and opportunity. Revisit and reprioritize the backlog regularly. Factor in total size to prevent overwhelming teams with large refactoring efforts. Consider segmenting compound debts into multiple incremental repayment stories for parallel team focus.
Allocating Capacity for Refactoring Work
Successful teams dedicate at least 10-20% of capacity to reducing technical debt. Without this, teams tend to continuously accumulate debt. Schedule recurring refactoring efforts in each sprint after factoring iteration objectives. Automate regression testing so refactoring can happen rapidly without fear of breaking existing behavior. Slowly repay bigger debts in installments vs batching all refactoring to “hardening sprints” at the end of long periods of feature work.
Preventing New Technical Debt
Retiring old technical debt is pointless unless new debt stops accumulating at a faster rate. Teams must define engineering practices as part of their “definition of done” and enable time for those activities as part of sustained velocity.
Adding Quality Checks in Definition of “Done”
Expand the quality practices required for a story to meet “definition of done”. Enforce standards like 80% unit test coverage, static analysis clean code checks, peer review approvals and staging deployment verification for all completed items.
Code Reviews and Static Analysis
Enable early detection of structural weaknesses and antipatterns while code is still easy to remediate. Perform peer-based human review of all source code before final commit. Combine with static analysis tools integrated into build processes to automatically catch bugs and quality issues.
Test-driven development
Require automated test cases to exercise new code and validate contracts before implementation. Not only does this prevent defects, but provides safety nets enabling future refactoring and enhancement efforts.
Finding and Fixing Defects
Even strong quality practices allow some defects to leak into production. Customers expect relatively defect-free increments from Scrum teams thanks to extensive testing processes. Fixing live defects distracts teams from delivering new value so should be minimized.
Testing and Validation in Sprints
Scrum teams focus on delivering “potentially shippable increments” at the end of each sprint. All items must satisfy the “definition of done” including test coverage standards, security scans, peer reviews etc. Extensive automated regression testing prevents accidental breaks. Only release-quality items should reach staging deployment for exploratory end user testing.
Tracking Defects in Product Backlog
When issues inevitably occur in production, capture them as high priority support items in the backlog. Categorize, estimate, and assign upcoming sprint capacity for fixing defects. Start shifting investment towards prevention by analyzing defect root causes for patterns.
Fixing Defects in Subsequent Sprints
Schedule defects as top priority product backlog items for the next sprint. Pull required team members off of discretionary new feature work to swarm on rapid fixes and testing before redeployment. Build regression test harnesses preventing future reoccurrence. Adjust practices that enabled defects based on root cause.
Measuring Quality
There is truth in the adage “you get what you measure”. Tracking quality metrics motivates teams to pursue excellence over just feature output.
Tracking Defect Trends Over Sprints
Measure total production defects and monitor trends sprint-over-sprint. Break down by severity, source, type and originating component. Establish goals for systematically reducing defects quarter by quarter. Reward teams for achieving quality targets ahead of feature output goals.
Using Metrics Like Code Coverage and Maintainability
Instrument engineering practices to monitor comprehensive quality metrics over time. Assess test coverage, technical debt ratings, code complexity trends, duplication rates, static analysis issues and security findings sprint-over-sprint. Continuous measurement enables early detection of quality erosion and targeting specific areas for improvement.
Conclusion
Key Takeaways for Managing Tech Debt and Defects in Scrum
- Define and measure quality standards in “definition of done”
- Allocate recurring team capacity for repaying technical debt
- Prioritize addressing defects over new features
- Inspect and adapt practices based on quality metric trends
- Empower teams to build true shippable increments sprint-over-sprint
The inspect-and-adapt cycles of Scrum provide the feedback loops required for sustainable development speed. By vigilantly monitoring and addressing technical debt and defects, teams can maintain velocity over years of active feature enhancements rather than allowing entropy to slow progress to a crawl.