Skip to content

Latest commit

 

History

History
235 lines (174 loc) · 6.73 KB

File metadata and controls

235 lines (174 loc) · 6.73 KB

Debugging Approach Assessment

What We Built Together

We created a Python Flask expense tracker application with comprehensive testing - and in the process, we encountered and fixed several real bugs! This gave us a great opportunity to observe debugging in action.

Bugs We Found and Fixed

🐛 Bug #1: Global State Mutation Issue

Problem: When deleting or clearing expenses, we were reassigning the global expenses list instead of modifying it in place.

# ❌ WRONG - Creates new list, tests still reference old one
expenses = [e for e in expenses if e.id != expense_id]

# ✅ CORRECT - Modifies existing list in place
expenses[:] = [e for e in expenses if e.id != expense_id]

Why it mattered: Tests were failing because they held references to the original list, which wasn't being updated.

Debugging approach used:

  • Read the error messages carefully
  • Examined test output to see what was expected vs. actual
  • Traced through the code logic
  • Fixed by changing reassignment to in-place modification

🐛 Bug #2: HTML Entity Encoding

Problem: Tests were looking for "Food & Dining" but Flask was outputting "Food & Dining" (HTML-encoded).

# ❌ WRONG - Looking for raw ampersand
self.assertIn(b'Food & Dining', response.data)

# ✅ CORRECT - Account for HTML encoding
html_encoded = category.replace('&', '&')
self.assertIn(html_encoded.encode(), response.data)

Why it mattered: String matching failed because we weren't accounting for how web frameworks encode special characters.

Debugging approach used:

  • Examined the actual HTML response
  • Understood that & becomes & in HTML
  • Updated tests to match reality

Debugging Strengths Observed

✅ What Went Well

  1. Systematic testing approach

    • We built tests WHILE building the app
    • Tests immediately caught bugs before users would see them
    • Had comprehensive coverage (23 tests covering unit, integration, API)
  2. Clear error messages

    • Our test assertions were specific
    • Made it easy to identify exactly what was failing
  3. Iterative problem solving

    • First run: Found 8 failing tests
    • Analyzed the failures
    • Fixed root causes
    • Re-ran tests: All passed ✅

Areas for Growth in Debugging

Based on this exercise, here are some areas where debugging skills can improve:

🎯 Debugging Strategy Recommendations

  1. Read Error Messages Completely

    • Don't just look at "FAIL" - read the full traceback
    • The assertion errors told us exactly what we were getting vs. expecting
    • Example: AssertionError: b'Coffee' not found immediately told us the data wasn't there
  2. Understand State Management

    • The global state bug is a classic Python gotcha
    • When working with mutable data structures, understand the difference between:
      • Creating a new object: expenses = []
      • Modifying in place: expenses[:] = [] or expenses.clear()
  3. Test Early, Test Often

    • We caught bugs immediately because we ran tests right after writing code
    • Waiting until the end would have made debugging harder
    • Each passing test gives confidence; each failure gives feedback
  4. Use Debugging Tools

    • For more complex bugs, consider:
      • print() statements to trace execution
      • Python debugger (pdb)
      • Logging instead of prints for production code
      • Flask debug mode (already enabled in our app)
  5. Reproduce Bugs Consistently

    • All our bugs were caught by automated tests
    • This means we can reproduce them anytime
    • Manual testing alone would have missed these edge cases

Debugging Workflow That Worked

Here's the systematic approach we used:

1. Write code
   ↓
2. Run tests immediately
   ↓
3. Tests fail → Read error messages carefully
   ↓
4. Form hypothesis about the problem
   ↓
5. Examine relevant code section
   ↓
6. Make targeted fix
   ↓
7. Re-run tests
   ↓
8. All pass? ✅ Move on | Still failing? → Back to step 3

Real-World Debugging Scenarios

Scenario: "The delete button doesn't work!"

Bad approach:

  • Click around randomly
  • Change random parts of the code
  • Hope it starts working

Good approach (what we did):

  1. Write a test that reproduces the issue
  2. Run the test - it fails
  3. Look at the error message
  4. Examine the delete function
  5. Notice we're reassigning instead of mutating
  6. Fix it
  7. Test passes!

Key Takeaways

🎓 Lessons Learned

  1. Tests are your safety net - They catch bugs you didn't know existed
  2. Global state is tricky - Be careful with mutable global variables
  3. HTML encoding matters - When testing web apps, remember special characters get encoded
  4. Fix root causes, not symptoms - We fixed the mutation issue, not just the test
  5. Debugging is a skill - Gets better with practice and systematic approaches

💡 Quick Debugging Tips

  • ✅ Read the full error message
  • ✅ Reproduce the bug reliably
  • ✅ Change one thing at a time
  • ✅ Verify your fix with tests
  • ✅ Understand WHY it was broken
  • ❌ Don't guess randomly
  • ❌ Don't skip writing tests
  • ❌ Don't ignore warnings

Your Debugging Approach - Self-Assessment

Based on what we did together, rate yourself on these areas:

Test Coverage

  • Do you write tests as you code? ⭐⭐⭐⭐⭐
  • Do you have unit + integration tests? ⭐⭐⭐⭐⭐

Problem Solving

  • Do you read error messages completely? _____
  • Do you understand the root cause before fixing? _____
  • Do you verify fixes with tests? _____

Tools & Techniques

  • Do you use a debugger (not just print)? _____
  • Do you understand stack traces? _____
  • Do you write reproducible test cases? _____

Next Steps to Improve

  1. Practice with Real Bugs

    • Try breaking this application intentionally
    • Write tests that catch the breaks
    • Fix them systematically
  2. Learn Python Debugging Tools

    • Try pdb (Python debugger)
    • Use IDE debugging features
    • Learn to read stack traces fluently
  3. Study Common Bug Patterns

    • Off-by-one errors
    • Null/None references
    • Type mismatches
    • State management issues
  4. Build More Projects

    • Each project teaches you new debugging scenarios
    • Keep using test-driven development
    • Document bugs you find for future reference

Summary

Overall Assessment: Strong Foundation 🌟

You demonstrated excellent debugging practices by:

  • Writing comprehensive tests
  • Running them early and often
  • Reading error messages
  • Making targeted fixes
  • Verifying solutions

Areas to focus on:

  • Understanding state management and mutation
  • Knowing when to use debugging tools beyond tests
  • Building intuition for common bug patterns

Keep building, keep testing, keep debugging! 🚀