Try free
9 min read Guide 744 of 877

Test-Driven Development with GitScrum

TDD isn't just about testing - it's about design and confidence. GitScrum supports TDD workflows with task tracking that reflects the red-green-refactor cycle.

TDD Fundamentals

The TDD Cycle

RED-GREEN-REFACTOR CYCLE:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│        ┌────────────┐                                      │
│        │    RED     │  ← Write failing test               │
│        │  (Failing  │    "What should the code do?"       │
│        │   Test)    │                                      │
│        └─────┬──────┘                                      │
│              │                                              │
│              ▼                                              │
│        ┌────────────┐                                      │
│        │   GREEN    │  ← Write minimum code to pass       │
│        │ (Passing   │    "Make it work, nothing more"     │
│        │   Test)    │                                      │
│        └─────┬──────┘                                      │
│              │                                              │
│              ▼                                              │
│        ┌────────────┐                                      │
│        │  REFACTOR  │  ← Improve without breaking tests   │
│        │  (Clean    │    "Make it clean"                  │
│        │   Code)    │                                      │
│        └─────┬──────┘                                      │
│              │                                              │
│              └──────────→ Repeat                           │
│                                                             │
│ CYCLE TIME: Minutes, not hours                             │
│                                                             │
│ KEY RULES:                                                  │
│ • Never write code without a failing test                 │
│ • Write the minimum code to pass                          │
│ • Refactor only when tests are green                      │
│ • Run tests frequently                                     │
└─────────────────────────────────────────────────────────────┘

TDD Benefits

WHY TDD WORKS:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ DESIGN BENEFITS:                                            │
│ • Forces you to think about interface first               │
│ • Leads to modular, testable code                         │
│ • Catches design problems early                            │
│ • Results in simpler designs                               │
│                                                             │
│ QUALITY BENEFITS:                                           │
│ • Bugs caught immediately                                  │
│ • High test coverage naturally                             │
│ • Regression protection                                    │
│ • Confidence to refactor                                   │
│                                                             │
│ PRODUCTIVITY BENEFITS:                                      │
│ • Less time debugging                                      │
│ • Faster feedback                                          │
│ • Documentation through tests                              │
│ • Easier onboarding                                        │
│                                                             │
│ PSYCHOLOGICAL BENEFITS:                                     │
│ • Small wins (green tests)                                 │
│ • Confidence in code                                       │
│ • Safe to change                                           │
│ • Clear progress                                           │
│                                                             │
│ WITHOUT TDD:                                                │
│ Write code → Test later → Find bugs → Debug → Fix → Repeat│
│                                                             │
│ WITH TDD:                                                   │
│ Write test → Write code → Test passes → Refactor → Done   │
└─────────────────────────────────────────────────────────────┘

TDD in Practice

Example Workflow

TDD EXAMPLE - ADD TO CART:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ STORY: "As a user, I can add items to my cart"            │
│                                                             │
│ TDD CYCLE 1:                                                │
│                                                             │
│ RED: Write test                                            │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ test('adds item to empty cart', () => {                ││
│ │   const cart = new Cart();                             ││
│ │   cart.add(item);                                      ││
│ │   expect(cart.items.length).toBe(1);                   ││
│ │ });                                                     ││
│ │ // Result: ❌ FAILS - Cart doesn't exist               ││
│ └─────────────────────────────────────────────────────────┘│
│                                                             │
│ GREEN: Write minimum code                                  │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ class Cart {                                           ││
│ │   items = [];                                          ││
│ │   add(item) { this.items.push(item); }                ││
│ │ }                                                       ││
│ │ // Result: ✅ PASSES                                   ││
│ └─────────────────────────────────────────────────────────┘│
│                                                             │
│ REFACTOR: (Nothing to refactor yet)                       │
│                                                             │
│ TDD CYCLE 2:                                                │
│                                                             │
│ RED: Next test                                             │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ test('increases quantity if item exists', () => {     ││
│ │   const cart = new Cart();                             ││
│ │   cart.add(item);                                      ││
│ │   cart.add(item);                                      ││
│ │   expect(cart.items.length).toBe(1);                   ││
│ │   expect(cart.items[0].quantity).toBe(2);             ││
│ │ });                                                     ││
│ │ // Result: ❌ FAILS - no quantity handling             ││
│ └─────────────────────────────────────────────────────────┘│
│                                                             │
│ GREEN: Add quantity logic                                  │
│ REFACTOR: Extract findItem method                         │
│                                                             │
│ Continue until all requirements covered...                │
└─────────────────────────────────────────────────────────────┘

Test Types

TDD TEST PYRAMID:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│                     /\                                      │
│                    /  \                                     │
│                   / E2E\     Few, slow, expensive          │
│                  /──────\                                   │
│                 /        \                                  │
│                /Integration\  Some, medium speed           │
│               /──────────────\                              │
│              /                \                             │
│             /    Unit Tests    \  Many, fast, cheap        │
│            /────────────────────\                           │
│                                                             │
│ UNIT TESTS (TDD Focus):                                     │
│ • Test single functions/methods                            │
│ • No external dependencies                                 │
│ • Milliseconds to run                                      │
│ • Write many of these                                      │
│                                                             │
│ INTEGRATION TESTS:                                          │
│ • Test components together                                 │
│ • May use database, API                                    │
│ • Seconds to run                                           │
│ • Write fewer of these                                     │
│                                                             │
│ E2E TESTS:                                                  │
│ • Test full user flows                                     │
│ • Real browser, real services                              │
│ • Minutes to run                                           │
│ • Write few, critical paths only                          │
│                                                             │
│ TDD PRIMARILY: Unit tests                                  │
│ ALSO USEFUL: Integration tests for key flows              │
└─────────────────────────────────────────────────────────────┘

TDD in GitScrum Workflow

Story with TDD

TDD INTEGRATED IN STORY FLOW:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ STORY: Add to Cart Functionality                          │
│                                                             │
│ STATUS: In Progress                                        │
│                                                             │
│ DEFINITION OF DONE:                                         │
│ ☐ All acceptance criteria met                             │
│ ☑ Unit tests written and passing                          │
│ ☐ Code reviewed                                           │
│ ☐ Integrated and deployed                                 │
│                                                             │
│ ─────────────────────────────────────────────────────────── │
│                                                             │
│ SUBTASKS (TDD Approach):                                   │
│                                                             │
│ ☑ Write tests for add to empty cart                       │
│ ☑ Implement add to empty cart                             │
│ ☑ Write tests for quantity increment                      │
│ ☑ Implement quantity increment                            │
│ ☐ Write tests for max quantity                            │
│ ☐ Implement max quantity                                  │
│ ☐ Write tests for out of stock                            │
│ ☐ Implement out of stock                                  │
│ ☐ Refactor and cleanup                                    │
│                                                             │
│ TEST COVERAGE:                                              │
│ Cart module: 94% coverage                                  │
│ All tests: ✅ 47 passing                                  │
│                                                             │
│ NOTE: Each test-implement pair is a mini red-green cycle  │
└─────────────────────────────────────────────────────────────┘

Tracking TDD Work

TDD IN TASK TRACKING:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ OPTION 1: Tests as part of story                          │
│                                                             │
│ Story: Add to cart                                         │
│ └── Subtasks:                                              │
│     ├── Tests for happy path                              │
│     ├── Implementation                                     │
│     ├── Tests for edge cases                               │
│     └── Refactoring                                        │
│                                                             │
│ ─────────────────────────────────────────────────────────── │
│                                                             │
│ OPTION 2: Tests implicit in definition of done            │
│                                                             │
│ Story: Add to cart                                         │
│ Definition of Done:                                        │
│ • Unit tests with 80%+ coverage                           │
│ • All tests passing                                        │
│ • Edge cases tested                                        │
│                                                             │
│ ─────────────────────────────────────────────────────────── │
│                                                             │
│ DO NOT:                                                     │
│                                                             │
│ ❌ "Testing" as separate story after development          │
│ ❌ "Write tests" as a sprint task after code              │
│ ❌ Skip tests when under time pressure                    │
│                                                             │
│ Tests are PART of development, not separate               │
└─────────────────────────────────────────────────────────────┘

Common Challenges

Starting with TDD

TDD ADOPTION TIPS:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ START SMALL:                                                │
│ • Start with new code, not legacy                         │
│ • Start with simple features                               │
│ • Pair with experienced TDD developer                     │
│                                                             │
│ LEARN THE RHYTHM:                                           │
│ • Resist urge to write more code than needed              │
│ • Keep cycles short (minutes)                             │
│ • Celebrate green tests                                    │
│                                                             │
│ COMMON MISTAKES:                                            │
│                                                             │
│ ❌ Tests too big                                          │
│ → Break into smaller tests                                 │
│                                                             │
│ ❌ Writing implementation first                           │
│ → Stop, delete, write test first                          │
│                                                             │
│ ❌ Not refactoring                                        │
│ → Schedule refactor time, it's essential                  │
│                                                             │
│ ❌ Skipping when rushed                                   │
│ → Rushing without tests creates more rush later           │
│                                                             │
│ TEAM ADOPTION:                                              │
│                                                             │
│ • Include in definition of done                           │
│ • Review tests in code review                              │
│ • Share testing patterns                                   │
│ • Celebrate test-first culture                             │
│ • Pair on complex features                                 │
└─────────────────────────────────────────────────────────────┘

When TDD Is Hard

CHALLENGING TDD SCENARIOS:
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│ UI COMPONENTS:                                              │
│ Challenge: Testing DOM, visuals                           │
│ Approach: Test behavior, not appearance                   │
│ Tools: Testing Library, Jest                               │
│ Tip: Separate logic from rendering                        │
│                                                             │
│ DATABASE/EXTERNAL SERVICES:                                 │
│ Challenge: Slow, stateful tests                           │
│ Approach: Mock external dependencies                      │
│ Tools: Mock libraries, test doubles                       │
│ Tip: Test integration separately                          │
│                                                             │
│ LEGACY CODE:                                                │
│ Challenge: Code not designed for testing                  │
│ Approach: Characterization tests first                    │
│ Tools: Approval tests                                      │
│ Tip: Refactor to testable design gradually               │
│                                                             │
│ UNCERTAIN REQUIREMENTS:                                     │
│ Challenge: Don't know what to test                        │
│ Approach: Spike first, then TDD                           │
│ Tip: Throw away spike code, rewrite with tests           │
│                                                             │
│ PERFORMANCE-CRITICAL:                                       │
│ Challenge: Need to optimize                               │
│ Approach: TDD for correctness, then optimize              │
│ Tip: Tests protect while optimizing                       │
│                                                             │
│ "If it's hard to test, the design might need work"        │
└─────────────────────────────────────────────────────────────┘