Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
A unit test tests one thing in isolation: one function, one class method, one business rule. The word 'isolation' is load-bearing: if your test touches a database, makes an HTTP call, or depends on another module's state, it is not a unit test — it's a small integration test. This distinction matters because isolated unit tests run in microseconds (you can run 10,000 per second), pinpoint exactly which piece of code broke (no need to debug which layer failed), and require no infrastructure (no test database, no network). The skill of writing testable code — structuring it so its dependencies can be replaced with fakes — is what separates SDETs from automation engineers who only test finished UIs.
Dependency injection is the design pattern that makes unit testing possible: instead of importing a database client directly, the function accepts it as a parameter, which lets tests pass a lightweight in-memory fake instead. Without this seam, every test would need a real database, real credentials, and real data — making the suite slow, environment-dependent, and fragile. Structuring code around injected dependencies is the single most impactful change an SDET can champion in a codebase.
formatEmailForDisplay(userId: int) -> str that returns a***@example.com (first char + *** + domain). Write 3 unit tests: valid email, missing user, email with no @ character. Each test should be independent — the others shouldn't need to pass for any one to pass.FakeUserRepo to raise an exception: raise ConnectionError('DB down'). Which tests fail? Which pass? This shows that unit tests should fail only when the unit under test is broken — not when its dependency fails.from database import db). Change it to accept the dependency as a parameter. Write the before/after tests. How did testability change?import pytest
# ✗ NOT a unit test — it calls the real database
# def test_user_exists():
# from db import get_user # imports the real module → real DB connection
# user = get_user(1)
# assert user.name == "Alice"
# ✓ Unit test — the dependency is injected (can be replaced with a fake)
class UserService:
def __init__(self, user_repo): # dependency injection via constructor
self._repo = user_repo
def get_display_name(self, user_id: int) -> str:
user = self._repo.find_by_id(user_id)
if user is None:
raise ValueError(f"User {user_id} not found")
return f"{user['first']} {user['last']}".title()
def is_premium(self, user_id: int) -> bool:
user = self._repo.find_by_id(user_id)
return user is not None and user.get("tier") == "premium"
# ── Tests ────────────────────────────────────────────────────────────────────
class FakeUserRepo:
"""In-memory fake — no database, no network, no I/O."""
def __init__(self, users: dict):
self._users = users
def find_by_id(self, user_id: int):
return self._users.get(user_id)
def make_service(users=None):
repo = FakeUserRepo(users or {1: {"first": "alice", "last": "smith", "tier": "premium"}})
return UserService(repo)
def test_display_name_title_cases_correctly():
svc = make_service()
assert svc.get_display_name(1) == "Alice Smith"
def test_display_name_raises_for_missing_user():
svc = make_service(users={}) # empty repo — user doesn't exist
with pytest.raises(ValueError, match="User 1 not found"):
svc.get_display_name(1)
def test_premium_user_is_identified():
svc = make_service()
assert svc.is_premium(1) is True
def test_free_user_is_not_premium():
svc = make_service(users={1: {"first": "bob", "last": "jones", "tier": "free"}})
assert svc.is_premium(1) is False
def test_missing_user_is_not_premium():
svc = make_service(users={})
assert svc.is_premium(99) is False
# Run: pytest -v → should show 5 passing tests with clear namespython3 main.py