Python Quest

Learning map · Track 13 · advanced

Testing and Software Quality

Working code is only half the job. The other half is knowing it works — today, after next week's change, and after someone else edits it. This track teaches you to write automated tests: small functions that call your code with chosen inputs and check the results, so a bug shows up as a failing test in seconds instead of a complaint from a customer weeks later. You start with plain assert statements, move to pytest (the tool most Python teams use), and learn the techniques that make tests worth having: checking exceptions and floating-point results correctly, hunting for edge cases at boundaries, writing table-driven tests with parametrize, keeping tests independent with fixtures and temporary files, and working test-first.

It is written for learners who have finished the earlier tracks and can write functions, classes and modules. Here the roles flip: in many exercises you write the tests, and the grader checks them by running them against deliberately broken versions of the code. A test that asserts nothing useful will not pass. You also use tests as a safety net to refactor messy code, make code readable with good names, small functions and type hints, see what tools like mypy and ruff catch before you run anything, and finish by debugging a pricing module the professional way: reproduce each bug as a failing test, fix it, and keep the test so the bug never returns.

By the end of this track you can

  • Write focused test functions with assert and pytest that pass on correct code and fail on realistic bugs
  • Test exceptions with pytest.raises and floating-point results with pytest.approx, and choose boundary and edge-case inputs deliberately
  • Organise tests with parametrize tables, fixtures and temporary files so each test is readable and independent
  • Work test-first (red, green, refactor) and refactor existing code safely with tests as a safety net
  • Improve readability with clear names, small functions, named constants, docstrings and type hints, and explain what static checkers catch
  • Debug by reproducing a bug as a failing test, fixing it, and keeping the regression test

Lessons

  1. 1Why we testWhat automated tests are for, how they differ from checking output by eye, and why they stop old bugs coming back.30 min · 3 exFree
  2. 2Writing tests with assertWrite test functions with assert, add helpful failure messages, and structure each test as arrange, act, assert.35 min · 3 exMembers
  3. 3Testing with pytestLet pytest find and run your tests, write them with plain asserts, and read its output to see exactly what failed.35 min · 3 exMembers
  4. 4Testing exceptions and floatsCheck that code raises the right exception with pytest.raises, and compare floating-point results safely with pytest.approx.40 min · 4 exMembers
  5. 5Thinking in edge casesFind the inputs that break code: boundaries, empty and single values, zero and negatives, messy text, unicode and very large values.40 min · 3 exMembers
  6. 6Table-driven tests with parametrizeWrite one test and a table of cases with pytest.mark.parametrize, so adding a case is one line and each case is reported separately.40 min · 3 exMembers
  7. 7Fixtures, setup and test isolationShare setup between tests with pytest fixtures, clean up with yield, use temporary files, and keep every test independent.45 min · 3 exMembers
  8. 8Test-driven developmentWrite the test first: red, green, refactor. Let small failing tests drive the design of new code and new features.45 min · 3 exMembers
  9. 9Refactoring safelyImprove the structure of working code without changing what it does, using tests as a safety net and characterization tests for legacy code.45 min · 3 exMembers
  10. 10Readable codeWrite code people can understand and change: clear names, small functions, named constants, no duplication, useful docstrings and PEP 8 layout.40 min · 3 exMembers
  11. 11Type hints and static checksDocument what functions accept and return with type hints, and let tools like mypy and ruff find bugs before the code runs.40 min · 3 exMembers
  12. 12Debugging with tests: a pricing moduleReproduce each bug as a failing test, fix it, and keep the test; then build a complete test suite for a small pricing module.70 min · 5 exMembers