Python reliability guide

Python Testing and Debugging with pytest

Test Python data code with pytest using fixtures and regression cases, then debug failures with focused runs and assertions that expose root causes.

How this page is maintained

Written for learners, checked against the sources below, and reviewed every year. Last reviewed July 22, 2026.

Short answer

Write tests for core transformations and edge cases before extending a script. pytest makes this practical with simple test discovery, readable assertions, and fixtures that keep test data setup consistent.

  • Test pure functions first because they are easiest to verify.
  • Use fixtures to share setup without duplicating test code.
  • Turn bug reports into regression tests before fixing logic.

Create useful tests for data workflows

Focus on deterministic functions such as parse_amount, normalize_channel, and aggregate_weekly_kpis. For each function, test normal inputs, boundary values, and invalid input handling.

Readable assertion messages help isolate failures quickly, especially when comparing DataFrame outputs where shape and column names both matter.

Debug failing cases systematically

When a test fails, reproduce with the smallest input that still fails. Inspect intermediate values and fix the root cause instead of updating expected outputs to match wrong behavior.

  • Use pytest -k to run only related tests during iteration.
  • Add temporary logging around transformation boundaries, then remove noise after resolution.
  • Keep tests independent so one failure does not hide others.

Add a regression test for malformed amount strings

A production bug showed amount values like 1,299.00 causing parse failures in one data source.

  1. Write a failing pytest test for parse_amount with input '1,299.00'.
  2. Update parsing logic to strip separators safely before conversion.
  3. Rerun the focused test and full test file to confirm no regressions.
Result: The bug is fixed with a permanent regression test that protects future changes.

Common mistakes

  • Testing only happy paths and missing malformed data cases.
  • Sharing mutable global test state across test functions.
  • Ignoring flaky tests instead of removing nondeterministic dependencies.
  • Fixing expected outputs to match broken logic without root-cause analysis.

Try one

Why should a real bug be converted into a test case before or with the fix?

It creates a regression guard so the same failure is caught automatically in future changes.

Sources

Learn this with a tutor

Tell LearnLive what you already know and what you need to do with testing and debugging.

Build this course