4D Training & Consultancy

Software Development

Testing Python Code with pytest

A working test suite is the difference between a change that ships and a change that waits. This course builds one with pytest: fixtures and scopes, parametrized cases, monkeypatch and mocks, coverage gates that resist gaming, fast CI runs, and a repeatable method for diagnosing flaky tests.

3 daysIn-house, online, or customized deliveryCorporate teams and professional groupsLevel: Intermediate

Overview

Practical learning for workplace transfer.

Teams rarely reject testing on principle; they abandon it because the suite became slow, brittle, and full of tests that fail for reasons unrelated to the change under review. This course builds a suite that stays worth running. Participants write behavior-focused tests, replace shared mutable test data with fixtures and factories, cover edge cases through parametrize and Hypothesis, and isolate databases, clocks, and HTTP calls with monkeypatch and fakes. The final day addresses the situations that actually erode confidence: flaky ordering-dependent tests, a coverage number that means nothing, and legacy code with no tests at all.

Prerequisites

Comfortable writing Python functions, classes, and modules. Familiarity with Git and running commands in a terminal is expected.

Objectives

  • Write focused pytest tests that assert on behavior rather than on implementation detail.
  • Structure fixtures, scopes, and conftest.py so test data stays isolated and reusable.
  • Cover boundary and error cases with parametrize, pytest.raises, and Hypothesis.
  • Isolate databases, clocks, and HTTP services using monkeypatch, fakes, and autospec mocks.
  • Set a coverage gate and a suite time budget that CI can enforce on every pull request.
  • Diagnose a flaky test to root cause and decide between fixing, quarantining, or deleting it.

Target audience

  • Python developers introducing tests into an untested codebase
  • QA engineers moving from manual checks to automated Python test suites
  • Data engineers validating transformation logic and pipeline outputs
  • DevOps engineers wiring test gates into build and deployment pipelines
  • Technical leads setting a definition of done for their team
  • Developers maintaining legacy Python that nobody dares to refactor

Program outline

A clear structure for the learning journey.

Program outline

Outline points are grouped in one designed block instead of being treated as separate module cards.

Module 1: A Test Suite That Earns Its Keep

pytest assertions, test discovery, and reading its failure output

Arrange, act, assert, and keeping one behavior per test

Drawing the unit, integration, and end-to-end boundaries in a Python project

Deciding what not to test and avoiding assertions on internal detail

Module 2: Fixtures and Test Data

Fixtures, function and session scopes, and teardown with yield

conftest.py and sharing fixtures across a test package

tmp_path and tmp_path_factory for filesystem isolation between tests

Factories and builders instead of one large shared test data blob

Module 3: Parametrization and Edge-Case Coverage

parametrize for tabular cases, boundary values, and regression examples

Stacked parametrization, custom ids, and readable test names in reports

Property-based testing with Hypothesis for input spaces too large to list

Asserting on exceptions, warnings, and error messages with pytest.raises

Module 4: Isolating Dependencies: Mocks, Fakes, and Stubs

monkeypatch for environment variables, the clock, and module attributes

unittest.mock with autospec, asserting calls without over-specifying them

Faking HTTP traffic with responses or respx instead of live services

Database tests using transactions, rollback, and disposable schemas

Module 5: Coverage, Speed, and Continuous Integration

pytest-cov, branch coverage, and setting a gate that cannot be gamed

pytest-xdist, test selection, and holding the suite to a time budget

Markers, separating slow tests, and running the right subset locally

Wiring pytest into CI with reports, artifacts, and required status checks

Module 6: Flaky Tests, Legacy Code, and Team Practice

Diagnosing flakiness: test ordering, shared state, time, and concurrency

Quarantine rules, retry policy, and when deleting a test is the right call

Adding characterization tests around legacy code before changing it

Agreeing a team testing standard and a written definition of done

Materials provided

  • Course workbook, annotated code samples, and reference notes
  • Hands-on lab environment and starter repositories
  • Exercises, checklists, and reusable code templates
  • 4D Certificate of Completion
  • Post-course technical guidance

Training Options

Programs can be delivered in-house, online, or in a blended format depending on your team's schedule, location, and learning objectives. When an external certificate or exam is included, certification rules and fees remain under the relevant awarding body's policies, while 4D provides the training and preparation support.

Why choose 4D

4D starts from your existing suite, or the absence of one, and measures its runtime and reliability before anything is written. Participants add characterization tests around a module their team is afraid to touch, then agree a coverage gate and a suite time budget that their own CI pipeline will enforce from the following week.

Speak to 4D

Plan the right training or consultancy path for your team.

Share a few details and 4D will help route your inquiry toward corporate training, consultancy, assessment, Phoenix-enabled support, or a tailored program.