Topic 17 of 64
Testing with pytest
Overview
Testing is the professional standard — pytest is the most popular Python testing framework. Writing tests prevents regressions, documents behavior, and is expected in any technical interview code challenge.
Syntax
python
# Install: pip install pytest pytest-cov
# test_math.py
import pytest
def add(a: int, b: int) -> int:
return a + b
# Test function (must start with test_)
def test_add_positive():
assert add(2, 3) == 5
def test_add_negative():
assert add(-1, 1) == 0
# Parametrize — run same test with multiple inputs
@pytest.mark.parametrize("a, b, expected", [
(2, 3, 5),
(-1, 1, 0),
(0, 0, 0),
])
def test_add_parametrized(a, b, expected):
assert add(a, b) == expected
# Exception testing
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
result = 10 / 0
# Fixtures
@pytest.fixture
def sample_user():
return {"id": 1, "name": "Priya", "role": "admin"}
def test_user_is_admin(sample_user):
assert sample_user["role"] == "admin"Common Pitfalls
- Test file names must start with test_ or end with _test.py for pytest to discover them automatically.
- Avoid testing implementation details — test behavior and contracts, not internal methods.
- Interview tip: pytest.fixture with scope='session' shares the fixture across all tests — useful for expensive setups like DB connections.
Real-World Example
Testing a shopping cart service with fixtures and mocks:
example
python
import pytest
from unittest.mock import Mock, patch
from cart_service import CartService
@pytest.fixture
def mock_db():
"""Fixture providing a mock database."""
db = Mock()
db.get_product.return_value = {
"id": "SKU-001", "name": "Laptop", "price": 45000, "stock": 5
}
return db
@pytest.fixture
def cart(mock_db):
"""Fixture creating a CartService instance."""
return CartService(db=mock_db)
class TestCartService:
def test_add_item(self, cart, mock_db):
cart.add_item("SKU-001", qty=2)
assert cart.item_count == 2
mock_db.get_product.assert_called_once_with("SKU-001")
def test_total_calculation(self, cart):
cart.add_item("SKU-001", qty=2) # 45000 × 2
assert cart.total == 90000
def test_insufficient_stock_raises(self, cart):
with pytest.raises(ValueError, match="Insufficient stock"):
cart.add_item("SKU-001", qty=10) # only 5 in stock
# Run: pytest test_cart.py -v --cov=cart_service