A follow-up to "Descriptive vs Prescriptive Testing" - Why the industry needs tests-first contracts for stakeholder alignment
Building on the Foundation
In my previous post about descriptive vs prescriptive testing, we explored how behavior-focused tests transform code reviews and create more resilient software. But that insight reveals a much deeper problem with how our industry approaches development.
What if the entire "code first, test later" paradigm is fundamentally backwards?
The more I've worked with behavior-focused testing, the more convinced I've become that we need a complete reframing of the development process - one that puts value contracts before implementation details.
The Systemic Devaluation Problem
But here's the deeper issue: testing isn't just devalued by developers - the entire decision chain devalues it.
The False Equation: Good Coders = Quality Code
Stakeholders and management operate under a dangerous assumption:
"We can achieve quality by just hiring good developers."
This thinking is fundamentally flawed because:
- ✨ Even the best developers write bugs - it's human nature
- 🧠 Complexity exceeds individual cognitive capacity - systems are too complex for perfect mental models
- 🏃 Delivery pressure corrupts judgment - time constraints lead to shortcuts
- 🤝 Quality emerges from process, not just talent - individual brilliance doesn't scale
The Quality vs. Delivery False Dilemma
Organizations create an artificial choice:
- 📦 "We want quality code" (in theory)
- 🚀 "But delivery rate is what matters" (in practice)
- ⏰ "Everything takes time, so delivery trumps quality" (the inevitable conclusion)
This creates a toxic cycle where:
- Management pushes for both quality and speed
- Teams know they can't deliver both under time pressure
- Quality gets sacrificed because delivery is measurable and visible
- Technical debt accumulates leading to slower future delivery
- Pressure increases to deliver even faster to compensate
- Quality degrades further and the cycle accelerates
The Hidden Cost of Quality Shortcuts
What stakeholders don't see is that skipping quality practices doesn't save time - it borrows it:
Short-term (Weeks 1-4)
- ✅ Faster initial delivery (no time spent on tests)
- ✅ Visible progress (features ship quickly)
- ✅ Happy stakeholders (getting what they asked for)
Medium-term (Months 2-6)
- ⚠️ Bug reports increase (quality issues surface)
- ⚠️ Hotfixes required (disrupting planned work)
- ⚠️ Development slows (technical debt accumulates)
Long-term (Months 6+)
- 🔴 Feature velocity crashes (codebase becomes unmaintainable)
- 🔴 Developer burnout (constant firefighting)
- 🔴 Customer satisfaction drops (reliability issues)
- 🔴 Competitive disadvantage (can't adapt quickly to market changes)
The Organizational Blind Spot
The problem is that quality debt is invisible until it's catastrophic:
- Delivery is measurable: "We shipped 12 features this quarter"
- Quality debt is hidden: Technical debt doesn't appear on roadmaps
- Bugs seem like isolated incidents: Each one gets treated as a one-off
- Slowdown seems like team performance: "Why is development taking longer?"
Management sees the immediate delivery wins but doesn't connect them to the later quality costs.
Breaking the Cycle: Tests-First as Business Strategy
This is why tests-first contracts aren't just a development practice - they're a business strategy.
When tests define value upfront:
- Stakeholders see exactly what they're getting before paying for it
- Quality becomes measurable (how many promises are we keeping?)
- Delivery becomes predictable (no surprise rework cycles)
- Technical debt becomes visible (broken tests show system degradation)
The conversation shifts from:
- ❌ "Why is this taking so long?" (adversarial)
- ✅ "Are we delivering on our promises?" (collaborative)
The Revolutionary Insight
While refactoring tests to be more descriptive, I realized something profound:
The teams that struggle most with testing are the ones focused on "how" instead of "what."
When developers say "I don't know what to test until I write the code," they're revealing that they're thinking about implementation before understanding the value they're supposed to deliver.
This backwards thinking is the root cause of:
- 🎯 Missed requirements (we build first, validate later)
- 🔄 Endless rework (stakeholders see the wrong thing)
- 💸 Wasted effort (features that don't deliver value)
- 🤷 Unclear expectations (no shared understanding)
- 🐛 Bug-driven development (testing becomes an afterthought)
The Paradigm Shift: Tests as Stakeholder Contracts
Imagine if we flipped the entire development process:
❌ Current Paradigm: Implementation-Driven
- Stakeholders describe what they want (vaguely)
- Engineers interpret and build something
- QA tests if the implementation works
- Stakeholders see it and say "This isn't what we meant"
- Repeat until exhausted or deadline hits
✅ New Paradigm: Value-Driven
- Tests written first as stakeholder agreements on value
- All parties review and agree on the behavioral contracts
- Implementation begins only after promise alignment
- Code reviews focus on "Does this fulfill our contracts?"
- Delivery means all promises are kept
From "I Don't Know What to Test" to "What Value Am I Promising?"
The most common pushback to tests-first approaches reveals the core problem:
"I don't know what to test until I write the code."
This statement shows implementation-first thinking. Let's reframe it:
Implementation-First Conversation
- "I need to build a user authentication system"
- "I'll use JWT tokens and a database"
- "Now I need to test if my JWT implementation works"
Value-First Conversation
- "Users need to securely access their accounts"
- "Users should stay logged in across sessions"
- "Users should get clear feedback when login fails"
- "Unauthorized users should never access protected data"
Notice: The second approach immediately suggests what to test, and none of it mentions JWT tokens.
The value-first conversation creates natural test contracts that all stakeholders can understand and agree on.
Tests as a Common Language
When tests are written first as behavioral contracts, they become a shared language:
- Product Managers: "These tests prove we deliver user value"
- Business Stakeholders: "These tests validate our requirements"
- Engineers: "These tests define our success criteria"
- QA Teams: "These tests guide our validation strategy"
- Support Teams: "These tests explain what the system does"
Real Example: Transforming Feature Requests
Business Request: "We need better data quality monitoring"
Traditional Approach:
- Engineers build a monitoring dashboard
- QA tests if the dashboard works
- Business sees it: "This isn't what we meant"
Tests-First Contract Approach:
def test_analysts_get_alerted_when_data_quality_degrades():
"""When data quality drops below thresholds, analysts receive
actionable alerts within 5 minutes."""
def test_business_users_can_see_data_health_trends():
"""Business users can view data quality trends over time
without technical knowledge required."""
def test_engineers_can_drill_down_to_root_causes():
"""When alerts fire, engineers can trace from symptom
to root cause in under 3 clicks."""
Now everyone knows exactly what "better monitoring" means before any code is written.
The Three-Phase Development Contract
Building on the descriptive testing foundation, here's how value-driven development works:
Phase 1: Value Definition (The Contract)
- Stakeholders define outcomes they need
- Tests written as behavioral contracts
- All parties review and agree on promises
- Edge cases identified before implementation
- Success criteria crystal clear
Phase 2: Implementation (Fulfilling the Contract)
- Engineers implement to fulfill test contracts
- Code reviews focus on quality, not requirements
- Refactoring is safe (contracts don't change)
- Progress is measurable (which contracts fulfilled?)
Phase 3: Delivery (Contract Validation)
- All tests pass = all promises kept
- Stakeholders validate against agreed contracts
- Documentation current (tests describe behavior)
- Maintenance predictable (contracts define boundaries)
Beyond TDD and BDD: Meta-Development
This isn't anti-TDD or anti-BDD - it's meta-TDD that operates at the stakeholder level:
- TDD says: Write tests first for better code
- BDD says: Write behavior specs for better requirements
- Value-Driven says: Write stakeholder contracts for better outcomes
The natural progression becomes:
- Tests-first contracts (stakeholder alignment)
- BDD specifications (behavior definition)
- TDD implementation (code quality)
Each layer reinforces the others, creating a value-driven development culture.
Practical Implementation: Start Small, Think Big
Week 1: Single Feature Experiment
- Pick one feature for the tests-first approach
- Write behavioral tests with stakeholders first
- Get unanimous agreement before implementation
- Implement only to fulfill contracts
- Measure the difference in rework and satisfaction
Month 1: Team Adoption
- Share experiment results with the team
- Train on value-first thinking patterns
- Update review processes to include test contracts
- Adjust tooling to support tests-first workflow
Quarter 1: Cultural Transformation
- Establish tests-first as standard practice
- Reward teams that deliver on contracts with minimal rework
- Make test contracts part of feature planning
- Celebrate when implementation matches promises exactly
The Reframing Questions
When teams resist with "We don't know what to test," help them reframe:
Instead of asking:
- "How should this function work?"
- "What should this API return?"
- "How do we structure this data?"
Ask:
- "What problem does this solve for users?"
- "How will users know this is working?"
- "What happens when this goes wrong?"
- "What value does this create?"
The answers become your test contracts - before any implementation exists.
Why This Matters Beyond Better Code
This reframe addresses fundamental problems in software development:
For Organizations
- Predictable delivery: Know what you're getting before you build it
- Reduced waste: Stop building the wrong things
- Stakeholder alignment: Everyone agrees on outcomes upfront
For Teams
- Clear direction: Implementation has a target, not wandering
- Protected refactoring: Contracts survive implementation changes
- Faster reviews: Focus on code quality, not requirements interpretation
For Users
- Better products: Built with clear understanding of user needs
- Fewer bugs: Edge cases identified before implementation
- Consistent experience: Behavior is defined and validated
The Bottom Line: From Code-Driven to Value-Driven
The current paradigm treats tests as validation after the fact.
The new paradigm treats tests as the first draft of value.
When we write tests first as stakeholder contracts:
- Requirements become concrete instead of abstract
- Teams align on specific outcomes before building
- Implementation has clear direction instead of wandering
- Quality is designed-in instead of tested-in
- Delivery becomes predictable instead of surprising
The Call to Revolution
This isn't just about better testing practices - it's about better software development.
We need an industry that asks "What value are we creating?" before "How should we build this?"
We need product managers who can articulate outcomes, not just features.
We need businesses that understand they're buying solutions, not code.
And we need tests that prove we delivered on our promises.
Tomorrow's Action Plan
- Pick your next feature
- Write the tests first with your stakeholders
- Get everyone to agree on what those tests promise
- Then and only then start coding
- Watch the transformation begin
Because when everyone agrees on what you're building before you build it, everything else becomes implementation details.
And implementation details should never drive the conversation. Value should.
This follow-up emerged from seeing how descriptive testing naturally leads to value-first thinking. The shift from "Does my code work?" to "Did I deliver what I promised?" changes everything.
No comments:
Post a Comment