Skip to content
advanced Phase 20 · Python Capstone Project

Implementation & Testing

Implement the Python application with comprehensive tests and documentation.

3h
0 problems
Topic Progress 0%

Implementing the Feature Slice

Implementing the Feature Slice

Build one vertical slice end to end before widening:

# services/orders.py
import logging
from collections.abc import Callable
from datetime import datetime
from proj.domain import Item, Order, Pricing
from proj.repositories import OrderRepo

log = logging.getLogger(__name__)

class OrderService:
    def __init__(self, repo: OrderRepo, clock: Callable[[], datetime]) -> None:
        self._repo, self._clock = repo, clock

    def place(self, items: list[Item]) -> Order:
        order = Pricing.price(items, at=self._clock())
        self._repo.save(order)
        log.info("order.placed id=%s", order.id)
        return order

Discipline per slice: full type hints, domain errors separate from infrastructure errors, raise ... from exc when wrapping, logging only at boundaries. Tests construct the service with fakes and a fixed clock.

Comprehensive Tests

Comprehensive Tests

# tests/unit/test_pricing.py
import pytest
from proj.domain import pricing

@pytest.mark.parametrize("qty,unit,expected", [
    (1, 100, 100), (3, 100, 270), (0, 100, 0),
])
def test_bulk_discount(qty, unit, expected):
    assert pricing.total(qty, unit) == expected

def test_rejects_negative_qty():
    with pytest.raises(pricing.PricingError, match="negative"):
        pricing.total(-1, 100)

Layered suite:

  • Unit: pure logic, monkeypatch for env, tmp_path for files — milliseconds
  • Integration: one real dependency (SQLite file, HTTP against a stub) — seconds
  • Contract: public API shape and error formats so refactors cannot silently break callers

Measure with pytest --cov=src --cov-fail-under=80; treat uncovered branches as the goal, not the percentage. Mutation tools (mutmut) audit whether assertions actually bite.

Docs and Release

Docs and Release

Documentation ships with the code, not after it:

  • README: install (pip install -e ".[dev]"), run, test — in that order, copy-pasteable
  • Docstrings: Google or NumPy style on every public function; Args/Returns/Raises sections
  • CHANGELOG: Keep a Changelog format — Added / Changed / Fixed per version
  • Type hints + mypy are living documentation IDEs consume

Release hygiene: semantic versioning (breaking → major), python -m build + twine check for sdist/wheel correctness, tags trigger CI publish with trusted credentials, and pre-commit run --all-files gates the commit that starts a release. Interview answer: correctness comes from tests + types + review working together; onboarding speed comes from a README that answers "how do I run this" in under a minute.

Quiz

1. Why inject a clock into OrderService instead of calling datetime.now() inside?

Question 1 options

2. What does --cov-fail-under=80 do?

Question 2 options

3. Which change requires a major version bump under semver?

Question 3 options

Flashcards

Question

Vertical slice

Answer

One feature through all layers (input → logic → storage → output) before starting the next.

Question

parametrize

Answer

Expands one test function into many cases — tables of inputs/outputs without copy-paste.

Question

Coverage floor

Answer

pytest --cov-fail-under=N enforces a minimum in CI; aim at missed branches, not the number.

Question

Keep a Changelog

Answer

Structured Added/Changed/Fixed sections per version — readable by humans and release tools.

Revision Notes

Key Takeaways

  • 1. Inject collaborators (repo, clock, client) so services unit-test without monkeypatching
  • 2. Layer tests by cost — fast pure units, targeted integrations, thin end-to-end
  • 3. Docs, changelog, and version discipline are part of done, not a post-launch task

Interview Tips

  • • Walk a reviewer through one slice: types, errors, logging points, and the tests that pin each behavior
  • • Explain how you decide what deserves coverage attention (branches and boundaries, not line count vanity)

Cheat Sheet

inject deps+clock; raise from exc; log at boundaries; unit/tmp_path/integration/contract tiers; pytest --cov-fail-under=80; semver + build + twine check.

Continue Learning