Menu
Courses / python advanced / Testing & Debugging

Testing & Debugging

08 / 10 Part of python advanced




 

    🎓 Advanced · Topic 08
 

 


    Testing & Debugging
 


 


    Write automated tests with pytest, mock external dependencies, measure coverage, and use Python's debugging tools to squash bugs fast.
 


 

    ⏱ ~60 min
    🔴 Advanced
    ✅ Quality
 


 
 

   

     
     

pytest Basics


   

   


      pytest discovers tests automatically: any file named test_*.py and any function prefixed test_ is a test. No boilerplate classes required.
   


   

     

        test_math.py
     

     
# The function under test
def divide(a: float, b: float) -> float:
    if b == 0:
        raise ValueError("Cannot divide by zero")
    return a / b

# Tests
def test_divide_normal():
    assert divide(10, 2) == 5.0

def test_divide_float():
    assert divide(1, 3) == pytest.approx(0.333, rel=1e-2)

def test_divide_by_zero():
    import pytest
    with pytest.raises(ValueError, match="Cannot divide"):
        divide(5, 0)

   

   

     

        Terminal — running pytest
     

     
pytest                         # run all tests
pytest test_math.py -v         # verbose output
pytest -k "divide" -v          # filter by name
pytest --cov=. --cov-report=html # coverage report

   

 


 
 

   

     
     

Fixtures & Parametrize


   

   

Fixtures set up shared test state. @pytest.mark.parametrize runs one test with multiple input/output pairs.


   

     

        conftest.py + test_user.py
     

     
import pytest

@pytest.fixture
def sample_user():
    return {"name": "Alice", "age": 30}

def test_user_name(sample_user):
    assert sample_user["name"] == "Alice"

@pytest.mark.parametrize("a,b,expected", [
    (2, 3, 5),
    (0, 0, 0),
    (-1, 1, 0),
])
def test_add(a, b, expected):
    assert a + b == expected  # runs 3 times

   

 


 
 

   

     
     

Mocking with unittest.mock


   

   

Replace real dependencies (databases, APIs, the clock) with controlled fakes to make tests fast and deterministic.


   

     

        test_api.py
     

     
from unittest.mock import patch, MagicMock
import requests

def get_username(user_id):
    r = requests.get(f"https://api.example.com/users/{user_id}")
    return r.json()["name"]

def test_get_username():
    mock_resp = MagicMock()
    mock_resp.json.return_value = {"name": "Alice"}

    with patch("requests.get", return_value=mock_resp):
        result = get_username(1)

    assert result == "Alice"   # no real HTTP call made

   

   

      🐛 Debugging tip — use breakpoint()
     

Drop breakpoint() anywhere in your code to launch the Python debugger (pdb). Type n to step, p var to inspect, c to continue, q to quit.