| name | python-testing |
| description | Use when implementing new Python code (follow TDD), designing test suites, reviewing test coverage, setting up pytest infrastructure, writing fixtures, mocking dependencies, or performing parametrized testing |
Python Testing Patterns
Comprehensive testing strategies for Python applications using pytest, TDD methodology, and best practices.
When to Use
- Writing new Python code (follow TDD: red, green, refactor)
- Designing test suites for Python projects
- Reviewing Python test coverage
- Setting up testing infrastructure
- Need guidance on fixtures, mocking, or parametrization
TDD Cycle
Always follow the Red → Green → Refactor cycle:
- RED: Write a failing test for the desired behavior
- GREEN: Write minimal code to make the test pass
- REFACTOR: Improve code while keeping tests green
Quick Start
import pytest
def test_addition():
assert 2 + 2 == 4
@pytest.fixture
def sample_data():
return {"name": "Alice", "age": 30}
def test_sample_data(sample_data):
assert sample_data["name"] == "Alice"
@pytest.mark.parametrize("input,expected", [
("hello", "HELLO"),
("world", "WORLD"),
])
def test_uppercase(input, expected):
assert input.upper() == expected
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
_ = 1 / 0
Core Topics
Fixtures
Setup and teardown for tests, sharing data, and scopes (function, module, session).
Details: references/fixtures.md
Parametrization
Running tests with multiple inputs using @pytest.mark.parametrize.
Details: references/parametrization.md
Mocking and Patching
Using unittest.mock to mock external dependencies and API calls.
Details: references/mocking.md
Markers and Test Selection
Custom markers (@pytest.mark.slow) and selective test execution.
Details: references/markers.md
Async Testing
Testing async functions with pytest-asyncio.
Details: references/async_testing.md
Test Organization
Directory structure, conftest.py, and grouping related tests.
Details: references/test_organization.md
Quick Reference
| Pattern | Usage |
|---|
pytest.raises() | Test expected exceptions |
@pytest.fixture() | Create reusable test fixtures |
@pytest.mark.parametrize() | Run tests with multiple inputs |
@pytest.mark.slow | Mark slow tests |
pytest -m "not slow" | Skip slow tests |
@patch() | Mock functions and classes |
tmp_path fixture | Automatic temp directory |
pytest --cov | Generate coverage report |
Running Tests
pytest
pytest --cov=mypackage --cov-report=html
pytest -m "not slow"
pytest -v
pytest -x
pytest --lf
Best Practices
DO:
- Follow TDD (write tests before code)
- Test one thing per test
- Use descriptive test names
- Use fixtures to eliminate duplication
- Mock external dependencies
- Aim for 80%+ coverage
- Keep tests fast
DON'T:
- Test implementation details
- Use complex conditionals in tests
- Share state between tests
- Catch exceptions in tests (use
pytest.raises)
- Write tests that are too brittle
Details: references/best_practices.md
Common Patterns
API Endpoint Testing
@pytest.fixture
def client():
app = create_app(testing=True)
return app.test_client()
def test_get_user(client):
response = client.get("/api/users/1")
assert response.status_code == 200
Database Testing
@pytest.fixture
def db_session():
session = Session(bind=engine)
session.begin_nested()
yield session
session.rollback()
session.close()
More patterns: references/common_patterns.md