GuideBeginner
Testing Fundamentals and TDD
Learn to test software from the ground up: what makes a test good, and the TDD cycle (red-green-refactor), hands-on with pure domain logic in Python using `pytest`. You start by writing tests by hand with `assert`, no framework at all, so the concept sticks before any tool automates it away; then you install `pytest` and practice the test-first rhythm until writing the test first starts to change how you design your code. The guide covers equivalence classes and boundary values, `pytest.raises` for exceptions, `@pytest.mark.parametrize` for case tables, tests that read well and don't break, coverage with `coverage.py` (and why 100% isn't the goal), and closes by teaching you to smell a test that's getting in the way and to control your first dependency with a simple test double. The whole path works on Reservo, a coworking room-booking system made of pure in-memory logic (no database, no network) — the perfect ground to practice on without infrastructure getting in the way. It closes with a final project where you build Reservo's cancellation-and-refund policy from scratch with TDD.
- 64
- lessons
- 8
- modules
- English · Spanish
- available in
- Yes
- certificate
- Free
- access
Outcomes
What you'll be able to do
- Define what makes a test good (fast, isolated, deterministic, readable), and write tests by hand with `assert` before ever touching a framework
- Install and use `pytest`: test discovery, assertions, running subsets with `-k`/`-x`/`-q`, and reading red/green output
- Practice the full TDD cycle (red-green-refactor) test-first, seeing how writing the test first changes your code's design
- Cover cases and edges with equivalence classes, boundary values, `pytest.raises` for exceptions, and `@pytest.mark.parametrize` for case tables
- Write tests that read well and don't break: names that document, the Arrange-Act-Assert pattern, one concept per test, and basic `pytest` fixtures
- Measure and read coverage with `coverage.py`/`pytest --cov` without turning it into a fetish, understanding what coverage does NOT see
- Recognize test smells (testing implementation, over-testing, slow or non-deterministic tests) and use your first test double (a `Clock`/stub) to control time
- Apply TDD end to end on a real project: build Reservo's cancellation-and-refund policy, from red to green to refactor
Before you start
What you need to bring
It's for you if...
- Python devs who have never written a test, or write them "because it's required," without understanding what makes one good
- Devs who want to learn TDD with discipline, practicing the red-green-refactor cycle step by step
- Teams that run `pytest` without fully mastering it (test discovery, `parametrize`, basic fixtures)
- Devs chasing 100% coverage without knowing what it actually measures and what it misses
Requirements and materials
- Basic Python knowledge (functions, exceptions, classes, lists and dictionaries)
- Python 3.10+ installed locally (this guide was verified with Python 3.14 and pytest 9.1.1)
- No prior testing or `pytest` knowledge required — the guide starts from zero
Content
The syllabus, module by module
Open any of them to see its lessons.
- 1. Module introduction: a test is an executable assertion
- 2. What a test is and why we write them
- 3. What tests buy you
- 4. The cost of not testing
- 5. The anatomy of a test: Arrange-Act-Assert
- 6. The `assert` statement from the inside and a runner by hand
- 7. What makes a test good
- 8. Mini-project: your first hand-written test
- 1. Module introduction: from a hand-written `assert` to a test runner
- 2. Installing pytest and your first green run
- 3. How pytest discovers your tests
- 4. Plain `assert` and why pytest's message is so good
- 5. Reading the output: red, green, and the failure report
- 6. Running only what matters: `-k`, `-x`, `-q`, `-v`
- 7. Growing your suite: one concept per test
- 8. Project: a pytest suite for `price_cents`
- 1. Module introduction: testing the logic, not just the happy path
- 2. Equivalence classes: fewer tests, more cases covered
- 3. Boundary values: where bugs live
- 4. The exact boundary: what happens AT 48 hours?
- 5. Testing errors with `pytest.raises`
- 6. `parametrize`: one test, many cases
- 7. Choosing the cases that matter
- 8. Project: a parametrized boundary suite for `refund_cents`
- 1. Module introduction: a test that passes isn't the same as a good test
- 2. Names that document what the test verifies
- 3. Arrange-Act-Assert made visible
- 4. One concept per test
- 5. Fragile tests versus behavior tests
- 6. Fixtures to stop repeating setup
- 7. DRY in tests without losing clarity
- 8. Mini-project: refactor a fragile Reservo suite
- 1. Module introduction: coverage is an instrument, not a grade
- 2. What line coverage measures
- 3. Running `coverage.py` on Reservo
- 4. Reading the report: `Stmts`, `Miss`, `Cover`, `Missing`
- 5. The myth of 100%
- 6. Branch coverage versus line coverage
- 7. What coverage doesn't see: the test without an `assert`
- 8. Mini-project: raise the coverage and find the hole it doesn't expose
- 1. Module introduction: when a test gets in the way
- 2. Test the behavior, not the implementation
- 3. Over-testing: when more tests do harm
- 4. Slow tests and non-deterministic (flaky) tests
- 5. The `datetime.now()` problem
- 6. Inject the clock: pass `now` as a parameter
- 7. Your first double: a fixed clock (`FixedClock`)
- 8. Mini-project: make the `cancel` test deterministic with a `FixedClock`
- 1. Module introduction: the method over the quantity
- 2. The first red test for `cancel`
- 3. Make it green with the minimum
- 4. The refund boundaries inside `cancel`
- 5. A fake clock for a deterministic `now`
- 6. Refactor `cancel` under a green bar
- 7. The feature's coverage and the gap it doesn't expose
- 8. Project: deliver the cancellation feature
Common questions
What people usually ask
No limit. It's a free guide: come in whenever you like, as often as you like.
No. Modules run from easier to harder, but you can jump to the one you need. Progress is saved per lesson.
Whatever is needed is listed under “What you need to bring”, above. If nothing is listed there, you can start from zero.
In the Club's WhatsApp group, and every two weeks there's a live with an instructor where questions get worked through.
Yes. It's issued automatically once you finish every lesson, with a verifiable code you can share on LinkedIn.
Start whenever you like
What students say
These reviews are from enrolled students who completed at least 50% of the course. We moderate reviews only on content grounds (spam, offensive language, personal data), never for being critical or negative.
No approved reviews yet.
Be the first to share your experience!