Capitolo 12: Debugging, Logging & Testing

Tecniche per individuare e correggere bug, registrare eventi con il logging e scrivere test automatizzati.

Scarica chapter12.py

Obiettivi

1. Debugging

Inizia con chiamate strategiche a print():

def compute(x, y):
    print("DEBUG:", x, y)
    return x / y

compute(5, 0)  # ispeziona gli input

Usa pdb per i breakpoint:

import pdb

def buggy():
    a = 1
    pdb.set_trace()    # pausa qui
    b = 0
    return a / b

buggy()

2. Modulo Logging

Un’alternativa migliore ai print, con livelli e destinazioni:

import logging

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s [%(levelname)s] %(message)s",
    datefmt="%H:%M:%S"
)
logger = logging.getLogger(__name__)

logger.debug("Info di debug")
logger.info("Avvio completato")
logger.warning("Spazio su disco limitato")
logger.error("Si è verificato un errore")

Crea handler per file o stream:

fh = logging.FileHandler("app.log")
fh.setLevel(logging.WARNING)
logger.addHandler(fh)

3. Assertions

Usa assert per controlli di coerenza in fase di sviluppo:

def divide(a, b):
    assert b != 0, "b non deve essere zero"
    return a / b

Nota: le assert vengono rimosse con -O.

4. Test Unitari con unittest

Definisci casi di test estendendo unittest.TestCase:

import unittest
from chapter12 import divide

class TestMath(unittest.TestCase):
    def test_divide_normal(self):
        self.assertEqual(divide(10, 2), 5)

    def test_divide_zero(self):
        with self.assertRaises(AssertionError):
            divide(5, 0)

if __name__ == "__main__":
    unittest.main()

Esegui con python -m unittest o integralo nella CI.

5. pytest

pytest offre sintassi concisa e fixture:

# test_chapter12.py
import pytest
from chapter12 import divide

def test_divide():
    assert divide(9, 3) == 3

def test_divide_zero():
    with pytest.raises(AssertionError):
        divide(1, 0)

Installa con pip install pytest e avvia con pytest.

Esercizi

  1. Inserisci pdb.set_trace() in una funzione e esplora il flusso.
  2. Sostituisci print() con chiamate logging e analizza il file di log.
  3. Aggiungi assert a una funzione di validazione dati.
  4. Scrivi test unittest per un modulo calcolatrice (add, sub, mul, div).
  5. Ripeti i test in stile pytest e confronta.