Chapter 12: Debugging, Logging & Testing
Techniques to find and fix bugs, record events with logging, and write automated tests.
Downloadchapter12.py
Objectives
- Use print() and
pdb
for interactive debugging. - Configure the
logging
module: levels, formatters, handlers. - Differentiate
assert
statements from exceptions and logs. - Write basic unit tests with
unittest
and run them. - Learn about third-party testing tools like
pytest
.
1. Debugging Techniques
Start with strategic print()
calls:
def compute(x, y):
print("DEBUG:", x, y)
return x / y
compute(5, 0) # inspect inputs
Use the built-in pdb
for breakpoints:
import pdb
def buggy():
a = 1
pdb.set_trace() # pause here
b = 0
return a / b
buggy()
2. Logging Module
A better alternative to prints; supports levels and destinations:
import logging
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%H:%M:%S"
)
logger = logging.getLogger(__name__)
logger.debug("Debugging info")
logger.info("Startup complete")
logger.warning("Low disk space")
logger.error("An error occurred")
Create file or stream handlers for flexible output:
fh = logging.FileHandler("app.log")
fh.setLevel(logging.WARNING)
logger.addHandler(fh)
3. Assertions
Use assert
to check invariants during development:
def divide(a, b):
assert b != 0, "b must not be zero"
return a / b
Note: assert
statements are removed when Python runs with -O
.
4. Unit Testing with unittest
Create test cases by subclassing 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()
Run tests with python -m unittest
or integrate into your CI.
5. pytest Overview
pytest
offers concise syntax and fixtures:
# 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)
Install with pip install pytest
and run pytest
.
Exercises
- Insert
pdb.set_trace()
into a small function and step through it. - Switch
print()
calls tologging
at various levels and inspect the log file. - Add
assert
checks to a data-validation function. - Write
unittest
tests for a simple calculator module (add, sub, mul, div). - Try rewriting those tests in
pytest
style and compare.