Excellent.
DAY 29 is about professional survivability — code that doesn’t just work today, but keeps working months later.
Most real-world failures are not logic bugs — they’re untested changes.
🧠 DAY 29 — Testing, Debugging & Maintainability
(Unit tests, mocking, debugging & long-term code health)
🔑 CORE IDEA OF DAY 29
Good code is testable code.
Untested code is broken code — it just hasn’t failed yet.
Testing is not a formality. It’s engineering insurance.
1️⃣ The Testing Pyramid (Mental Model)




From bottom to top:
- Unit tests (many, fast)
- Integration tests (fewer)
- End-to-end tests (very few, slow)
🧠 Most confidence comes from unit tests.
2️⃣ What Is a Unit Test (Precisely)
A unit test:
- Tests one function or method
- In isolation
- With controlled inputs
- Deterministic outcome
Example:
def add(a, b):
return a + b
Test:
def test_add():
assert add(2, 3) == 5
No I/O. No network. No randomness.
3️⃣ Why Tests Fail in Real Projects
Common reasons:
- Code tightly coupled to I/O
- Hidden global state
- Side effects everywhere
- No separation of concerns
🧠 Testability is a design property, not a testing problem.
4️⃣ Writing Testable Code (Design Rules)
✔ Separate logic from I/O
✔ Pass dependencies explicitly
✔ Avoid globals
✔ Use pure functions where possible
Bad:
def get_user():
return db.query(...)
Good:
def get_user(db):
return db.query(...)
This enables mocking.
5️⃣ Assertions: What to Test
Test:
- Behavior
- Outputs
- State transitions
Avoid testing:
- Implementation details
- Private helper internals
- Exact timing (unless required)
Rule:
Test what, not how.
6️⃣ Mocking (CRITICAL for Interviews)
Mocking replaces real dependencies with fake ones.
Why:
- Network is slow
- DB is external
- File system is unpredictable
Conceptually:
def process(fetch):
data = fetch()
return data.upper()
Test:
def fake_fetch():
return "hello"
assert process(fake_fetch) == "HELLO"
No real network call needed.
7️⃣ Mocking vs Faking vs Stubbing
| Technique | Purpose |
|---|---|
| Stub | Return fixed data |
| Fake | Simplified implementation |
| Mock | Assert interactions |
In interviews, “mock” often means any of the above.
8️⃣ Debugging Strategy (Senior-Level)
Don’t randomly print.
Step-by-step approach:
- Reproduce reliably
- Minimize the failing case
- Inspect assumptions
- Narrow scope
- Fix root cause
- Add a test
🧠 Every bug fixed without a test will return.
9️⃣ Debugging Tools (Mental Toolkit)
- Tracebacks → where it broke
- Stack frames → how it got there
- Logging → what state looked like
- Assertions → validate invariants
Avoid:
print("here")
Prefer:
assert x is not None
🔟 Logging vs Printing (IMPORTANT)
Printing:
- For debugging locally
- Not structured
- Hard to filter
Logging:
- Levels (DEBUG, INFO, ERROR)
- Structured
- Production-safe
Rule:
Print for learning, log for systems.
11️⃣ Common Testing Anti-Patterns 🚨
❌ Tests depend on order
❌ Tests share mutable state
❌ Tests hit real APIs
❌ Tests break on minor refactors
❌ No assertions (only prints)
Interviewers spot these instantly.
12️⃣ Regression Tests (Why Bugs Stay Dead)
When a bug is found:
- Write a test that fails
- Fix the bug
- Keep the test forever
This is how large systems remain stable.
🔥 INTERVIEW TRAPS (DAY 29)
Q1
Why is mocking important?
✔ Isolation
✔ Speed
✔ Determinism
Q2
Why tests shouldn’t depend on real DBs?
✔ Slow
✔ Flaky
✔ Hard to control
Q3
What’s the difference between testing and debugging?
✔ Testing prevents bugs
✔ Debugging finds bugs
🧠 DAY 29 MENTAL CHECKLIST
Before shipping code:
- Can this be tested?
- Are edge cases covered?
- Are failures deterministic?
- Is there a regression test?
- Will future changes break silently?
📝 DAY 29 ASSIGNMENT (MANDATORY)
1️⃣ Identify design flaw:
def get_data():
import requests
return requests.get("http://api").json()
Why is this hard to test?
How would you redesign it?
2️⃣ Explain clearly:
- Difference between unit and integration tests
- Why tests are part of design, not QA
3️⃣ Design question:
How would you test a function that retries on network failure?
(Hint: dependency injection + mocks)
🔜 DAY 30 PREVIEW (FINAL DAY 🔥)
DAY 30 — Python Internals Recap + Interview Mastery
You’ll:
- Connect all concepts end-to-end
- Review CPython execution model
- Practice killer interview questions
- Build a final mental model of Python
When ready, say 👉 “START DAY 30”