| name | testing-python |
| description | Python testing with pytest: fixtures, parametrize, mocking with unittest.mock, and coverage |
Testing — Python
Framework
- pytest for all projects. Avoid
unittest for new code.
- Run:
pytest / pytest --cov=src --cov-report=term-missing
File Conventions
- Test files:
tests/test_<module>.py or co-located src/utils/test_format.py.
- Conftest: shared fixtures in
tests/conftest.py.
Test Structure
def test_format_date_returns_iso_string_for_valid_date():
date = datetime(2026, 1, 15)
result = format_date(date)
assert result == "2026-01-15"
Fixtures
@pytest.fixture
def db_session():
session = create_test_session()
yield session
session.rollback()
session.close()
def test_user_created(db_session):
user = create_user(db_session, name="Alice")
assert user.id is not None
Parametrize
@pytest.mark.parametrize("value,expected", [
("", True),
(" ", True),
("hello", False),
])
def test_is_blank(value, expected):
assert is_blank(value) == expected
Mocking
from unittest.mock import patch, MagicMock
def test_sends_email_on_signup(mock_smtp):
with patch("myapp.mailer.smtplib.SMTP") as mock_smtp:
send_welcome_email("user@example.com")
mock_smtp.return_value.sendmail.assert_called_once()
Coverage Targets
- Business logic: 85%+ branch coverage.
- Run
pytest --cov in CI; fail below threshold with --cov-fail-under=80.