
Python Testing
- 7.3k installs
- 238k repo stars
- Updated August 5, 2026
- affaan-m/everything-claude-code
python-testing is an agent skill for >
About
name python-testing description Python testing best practices using pytest including fixtures parametrization mocking coverage analysis async testing and test organization Use when writing or improving Python tests metadata origin ECC globs py pyi Python Testing This skill provides comprehensive Python testing patterns using pytest as the primary testing framework Testing Framework Use pytest as the testing framework for its powerful features and clean syntax Basic Test Structure python def test_user_creation Test that a user can be created with valid data user User name Alice email alice example com assert user name Alice assert user email alice example com assert user is_active is True Test Discovery pytest automatically discovers tests following these conventions Files test_ py or _test py Functions test_ Classes Test without __init__ Methods test_ Fixtures Fixtures provide reusable test setup and teardown python import pytest from sqlalchemy import create_engine from sqlalchemy orm import sessionmaker pytest fixture def db_session Provide a database session for tests engine create_engine sqlite memory Session sessionmaker bind engine session Session Setup Base metadata create_.
- Files: `test_*.py` or `*_test.py`
- Classes: `Test*` (without `__init__`)
- pytest.ini or pyproject.toml
- pytest shows: assert 5 == 6
- **One assertion per test** (when possible)
Python Testing by the numbers
- 7,258 all-time installs (skills.sh)
- +236 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #221 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
python-testing capabilities & compatibility
- Capabilities
- files: `test_*.py` or `*_test.py` · classes: `test*` (without `__init__`) · pytest.ini or pyproject.toml · pytest shows: assert 5 == 6 · **one assertion per test** (when possible)
- Use cases
- documentation
What python-testing says it does
--- name: python-testing description: > Python testing best practices using pytest including fixtures, parametrization, mocking, coverage analysis, async testing, and test organization.
Use when writing or improving Python tests.
metadata: origin: ECC globs: ["**/*.py", "**/*.pyi"] --- # Python Testing > This skill provides comprehensive Python testing patterns using pytest as the primary testing framework.
npx skills add https://github.com/affaan-m/everything-claude-code --skill python-testingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 7.3k |
|---|---|
| repo stars | ★ 238k |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 5, 2026 |
| Repository | affaan-m/everything-claude-code ↗ |
When should developers use python-testing and what problem does it solve?
>
Who is it for?
Developers working with python-testing patterns described in the skill documentation.
Skip if: Skip when cached docs are empty or the task is outside the skill's documented scope.
When should I use this skill?
>
What you get
Grounded guidance and workflows from SKILL.md for python-testing.
- pytest test files
- coverage reports
- TDD test suites
Files
Python Testing
This skill provides comprehensive Python testing patterns using pytest as the primary testing framework.
Testing Framework
Use pytest as the testing framework for its powerful features and clean syntax.
Basic Test Structure
def test_user_creation():
"""Test that a user can be created with valid data"""
user = User(name="Alice", email="alice@example.com")
assert user.name == "Alice"
assert user.email == "alice@example.com"
assert user.is_active is TrueTest Discovery
pytest automatically discovers tests following these conventions:
- Files:
test_*.pyor*_test.py - Functions:
test_* - Classes:
Test*(without__init__) - Methods:
test_*
Fixtures
Fixtures provide reusable test setup and teardown:
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
@pytest.fixture
def db_session():
"""Provide a database session for tests"""
engine = create_engine("sqlite:///:memory:")
Session = sessionmaker(bind=engine)
session = Session()
# Setup
Base.metadata.create_all(engine)
yield session
# Teardown
session.close()
def test_user_repository(db_session):
"""Test using the db_session fixture"""
repo = UserRepository(db_session)
user = repo.create(name="Alice", email="alice@example.com")
assert user.id is not NoneFixture Scopes
@pytest.fixture(scope="function") # Default: per test
def user():
return User(name="Alice")
@pytest.fixture(scope="class") # Per test class
def database():
db = Database()
db.connect()
yield db
db.disconnect()
@pytest.fixture(scope="module") # Per module
def app():
return create_app()
@pytest.fixture(scope="session") # Once per test session
def config():
return load_config()Fixture Dependencies
@pytest.fixture
def database():
db = Database()
db.connect()
yield db
db.disconnect()
@pytest.fixture
def user_repository(database):
"""Fixture that depends on database fixture"""
return UserRepository(database)
def test_create_user(user_repository):
user = user_repository.create(name="Alice")
assert user.id is not NoneParametrization
Test multiple inputs with @pytest.mark.parametrize:
import pytest
@pytest.mark.parametrize("email,expected", [
("user@example.com", True),
("invalid-email", False),
("", False),
("user@", False),
("@example.com", False),
])
def test_email_validation(email, expected):
result = validate_email(email)
assert result == expectedMultiple Parameters
@pytest.mark.parametrize("name,age,valid", [
("Alice", 25, True),
("Bob", 17, False),
("", 25, False),
("Charlie", -1, False),
])
def test_user_validation(name, age, valid):
result = validate_user(name, age)
assert result == validParametrize with IDs
@pytest.mark.parametrize("input,expected", [
("hello", "HELLO"),
("world", "WORLD"),
], ids=["lowercase", "another_lowercase"])
def test_uppercase(input, expected):
assert input.upper() == expectedTest Markers
Use markers for test categorization and selective execution:
import pytest
@pytest.mark.unit
def test_calculate_total():
"""Fast unit test"""
assert calculate_total([1, 2, 3]) == 6
@pytest.mark.integration
def test_database_connection():
"""Slower integration test"""
db = Database()
assert db.connect() is True
@pytest.mark.slow
def test_large_dataset():
"""Very slow test"""
process_million_records()
@pytest.mark.skip(reason="Not implemented yet")
def test_future_feature():
pass
@pytest.mark.skipif(sys.version_info < (3, 10), reason="Requires Python 3.10+")
def test_new_syntax():
passRun specific markers:
pytest -m unit # Run only unit tests
pytest -m "not slow" # Skip slow tests
pytest -m "unit or integration" # Run unit OR integrationMocking
Using unittest.mock
from unittest.mock import Mock, patch, MagicMock
def test_user_service_with_mock():
"""Test with mock repository"""
mock_repo = Mock()
mock_repo.find_by_id.return_value = User(id="1", name="Alice")
service = UserService(mock_repo)
user = service.get_user("1")
assert user.name == "Alice"
mock_repo.find_by_id.assert_called_once_with("1")
@patch('myapp.services.EmailService')
def test_send_notification(mock_email_service):
"""Test with patched dependency"""
service = NotificationService()
service.send("user@example.com", "Hello")
mock_email_service.send.assert_called_once()pytest-mock Plugin
def test_with_mocker(mocker):
"""Using pytest-mock plugin"""
mock_repo = mocker.Mock()
mock_repo.find_by_id.return_value = User(id="1", name="Alice")
service = UserService(mock_repo)
user = service.get_user("1")
assert user.name == "Alice"Coverage Analysis
Basic Coverage
pytest --cov=src --cov-report=term-missingHTML Coverage Report
pytest --cov=src --cov-report=html
open htmlcov/index.htmlCoverage Configuration
# pytest.ini or pyproject.toml
[tool.pytest.ini_options]
addopts = """
--cov=src
--cov-report=term-missing
--cov-report=html
--cov-fail-under=80
"""Branch Coverage
pytest --cov=src --cov-branchAsync Testing
Testing Async Functions
import pytest
@pytest.mark.asyncio
async def test_async_fetch_user():
"""Test async function"""
user = await fetch_user("1")
assert user.name == "Alice"
@pytest.fixture
async def async_client():
"""Async fixture"""
client = AsyncClient()
await client.connect()
yield client
await client.disconnect()
@pytest.mark.asyncio
async def test_with_async_fixture(async_client):
result = await async_client.get("/users/1")
assert result.status == 200Test Organization
Directory Structure
tests/
├── unit/
│ ├── test_models.py
│ ├── test_services.py
│ └── test_utils.py
├── integration/
│ ├── test_database.py
│ └── test_api.py
├── conftest.py # Shared fixtures
└── pytest.ini # Configurationconftest.py
# tests/conftest.py
import pytest
@pytest.fixture(scope="session")
def app():
"""Application fixture available to all tests"""
return create_app()
@pytest.fixture
def client(app):
"""Test client fixture"""
return app.test_client()
def pytest_configure(config):
"""Register custom markers"""
config.addinivalue_line("markers", "unit: Unit tests")
config.addinivalue_line("markers", "integration: Integration tests")
config.addinivalue_line("markers", "slow: Slow tests")Assertions
Basic Assertions
def test_assertions():
assert value == expected
assert value != other
assert value > 0
assert value in collection
assert isinstance(value, str)pytest Assertions with Better Error Messages
def test_with_context():
"""pytest provides detailed assertion introspection"""
result = calculate_total([1, 2, 3])
expected = 6
# pytest shows: assert 5 == 6
assert result == expectedCustom Assertion Messages
def test_with_message():
result = process_data(input_data)
assert result.is_valid, f"Expected valid result, got errors: {result.errors}"Approximate Comparisons
import pytest
def test_float_comparison():
result = 0.1 + 0.2
assert result == pytest.approx(0.3)
# With tolerance
assert result == pytest.approx(0.3, abs=1e-9)Exception Testing
import pytest
def test_raises_exception():
"""Test that function raises expected exception"""
with pytest.raises(ValueError):
validate_age(-1)
def test_exception_message():
"""Test exception message"""
with pytest.raises(ValueError, match="Age must be positive"):
validate_age(-1)
def test_exception_details():
"""Capture and inspect exception"""
with pytest.raises(ValidationError) as exc_info:
validate_user(name="", age=-1)
assert "name" in exc_info.value.errors
assert "age" in exc_info.value.errorsTest Helpers
# tests/helpers.py
def assert_user_equal(actual, expected):
"""Custom assertion helper"""
assert actual.id == expected.id
assert actual.name == expected.name
assert actual.email == expected.email
def create_test_user(**kwargs):
"""Test data factory"""
defaults = {
"name": "Test User",
"email": "test@example.com",
"age": 25,
}
defaults.update(kwargs)
return User(**defaults)Property-Based Testing
Using hypothesis for property-based testing:
from hypothesis import given, strategies as st
@given(st.integers(), st.integers())
def test_addition_commutative(a, b):
"""Test that addition is commutative"""
assert a + b == b + a
@given(st.lists(st.integers()))
def test_sort_idempotent(lst):
"""Test that sorting twice gives same result"""
sorted_once = sorted(lst)
sorted_twice = sorted(sorted_once)
assert sorted_once == sorted_twiceBest Practices
1. One assertion per test (when possible) 2. Use descriptive test names - describe what's being tested 3. Arrange-Act-Assert pattern - clear test structure 4. Use fixtures for setup - avoid duplication 5. Mock external dependencies - keep tests fast and isolated 6. Test edge cases - empty inputs, None, boundaries 7. Use parametrize - test multiple scenarios efficiently 8. Keep tests independent - no shared state between tests
Running Tests
# Run all tests
pytest
# Run specific file
pytest tests/test_user.py
# Run specific test
pytest tests/test_user.py::test_create_user
# Run with verbose output
pytest -v
# Run with output capture disabled
pytest -s
# Run in parallel (requires pytest-xdist)
pytest -n auto
# Run only failed tests from last run
pytest --lf
# Run failed tests first
pytest --ffWhen to Use This Skill
- Writing new Python tests
- Improving test coverage
- Setting up pytest infrastructure
- Debugging flaky tests
- Implementing integration tests
- Testing async Python code
Related skills
Forks & variants (1)
Python Testing has 1 known copy in the catalog totaling 1.5k installs. They canonicalize to this original listing.
- affaan-m - 1.5k installs
FAQ
What does python-testing do?
>
When should I invoke python-testing?
>
Where is the source documentation?
Ground claims in SKILL.md excerpts and linked reference files from the cached docs.
Is Python Testing safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.