📝 Practice Exercises
Practice Exercises: Exercise 1: Parse Test Results Write a function parse_results(results) that takes a list of dicts (each with a "status" key: "PASS", "FAIL", or "SKIP") and re
Exercise 1: Parse Test Results
Write a function parse_results(results) that takes a list of dicts (each with a "status" key: "PASS", "FAIL", or "SKIP") and returns a dict with counts: {"PASS": N, "FAIL": N, "SKIP": N, "total": N}.
Initialize counts before the loop. .get() with default avoids KeyError. Add "total" at the end so it reflects all items including unknowns.
Exercise 2: APIClient Class
Create class APIClient with base_url, and get(path) / post(path, data) methods returning parsed JSON. Handle ConnectionError (return None), Timeout (return None), HTTPError (raise). Use requests.Session for connection reuse.
Session reuses TCP connections reducing overhead. Separating network errors (return None) from HTTP errors (raise) gives callers different options.
Exercise 3: pytest conftest with Session DB + CSV Parametrize
Write conftest.py with session-scoped SQLite fixture (creates users table). Write test_users.py that loads test data from CSV via parametrize and validates each user's email in the DB.
Session scope: DB persists across all tests (efficient). Each test cleans up its own data to avoid state leaking between tests. parametrize drives multiple scenarios from one function.
Quick Reference Card
Run "python -m pytest -v --tb=short" for verbose output with compact tracebacks. Add "--headed" to Playwright to see the browser while debugging.
What is the main benefit of using a context manager like `with open("f.txt") as f:`?
It reads the file faster
It automatically closes the resource when the block ends (even on error), so you never write try/finally