The pyramid's dome, small and stable. No solutions.md before submitting.
Exercise 1 — The catalog
- List TicketFlow's business stories and mark the ones entering the E2E catalog (target: ≤ 8 for your scope). For each: the full HTTP flow and which dependency gets doubled.
- The ones that DON'T enter: list 5 edge cases you were tempted to push up to E2E and reassign them to their real layer (serializer→unit, permissions→integration, etc.).
- Run
pytest -m e2e --collect-only: the catalog is measurable. How many? How long would it take at 20 s/test?
Exercise 2 — The full purchase
- Implement the complete
test_compra_feliz(search → reserve → pay → confirm → ticket) withdrenar_cola()and asserts on the final STATE (reservation CONFIRMED, mailbox 1, seats SOLD). - The tragic story: declined payment → compensation (32). Asserts: state COMPENSATED, seat free again, failure email, webhook NOT sent (the third party doesn't get paid for a failed sale).
- The dispute story: two users, same seat, near-simultaneous payments → ONE CONFIRMED, the other compensated with a refund. The test of the guarantee the business sells.
Exercise 3 — The flaky, hunted
- Plant a flaky on purpose: a test doing
time.sleep(1)and then asserting the saga's state (fails on slow machines). Switch it towait_forwith a 5 s deadline: does it run stable 10 times in a row? (pytest --count=10or a loop). - The state dump: add to
wait_forthe dump (saga state, pending eager-queue tasks, last 3 outbox events). Break the flow on purpose (the payment doesn't confirm): is the dump enough to diagnose without opening the IDE? - The quarantine: define
@pytest.mark.flaky(or your marker) that in CI re-runs once with a report. The rule: max 2 tests in quarantine and a mandatory issue. Write the rule into CONTRIBUTING.md.
Exercise 4 — The contract
- Write
CONTRATO_FRONTwith the 6 interactions TicketFlow's front uses (listing, detail, reserve, pay, status, cancel) and the parametrized test validating them. - Break the contract on purpose: change
total(int) tototal(an object {amount, currency}) in the response. Which test goes red and after how many seconds? Now change the CONTRACT (the consumer accepts both for a sprint, 14: dual version) — how is that compatibility written in the test? - The error contract (26): add the problem+json rules (type, title, status) to the contract. Test: the disputed seat's 409 satisfies the error contract.
Exercise 5 — The engine room
- Build the E2E compose (app + PG + Redis with healthchecks) and the clean reset between tests (truncation + Redis DB 15 flush). Measure: how long does the reset take? And "restarting the world" (compose down/up)? The difference is what you save ×N tests.
- The auth fixture (18):
comprador_autenticadothat creates the user, gets an access token and uses it in the client. No "manual" login in any test. - The health metric: run the catalog 20 times (or use the CI runs if they exist) and compute the flaky_rate. < 1%? If not: which test goes to quarantine and why?
Submit
Paste the catalog, the 3 story tests (happy/tragic/dispute), the contract with the break's red and the flakiness metric. Next: Lesson 36 — Load testing (k6).