skills/pytest/SKILL.md
Python testing mastery with pytest, fixtures, parametrize, mocking, and coverage. Use when user asks to "write tests", "add pytest fixtures", "mock a function", "parametrize tests", "run coverage", "debug failing test", "set up conftest", or any Python testing tasks.
npx skillsauth add 1mangesh1/dev-skills-collection pytestInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Complete Python testing toolkit with pytest.
# Run all tests
pytest
# Run specific file/directory
pytest tests/test_api.py
pytest tests/
# Run specific test
pytest tests/test_api.py::test_login
pytest tests/test_api.py::TestUserClass::test_create
# Verbose output
pytest -v
pytest -vv # Extra verbose
# Stop on first failure
pytest -x
# Run last failed
pytest --lf
# Run failed first, then rest
pytest --ff
# Show print output
pytest -s
# Parallel (requires pytest-xdist)
pytest -n auto
pytest -n 4
import pytest
# Basic fixture
@pytest.fixture
def user():
return {"name": "Alice", "email": "[email protected]"}
# Fixture with teardown
@pytest.fixture
def db_connection():
conn = create_connection()
yield conn
conn.close()
# Autouse fixture (runs for every test)
@pytest.fixture(autouse=True)
def reset_state():
State.reset()
yield
State.cleanup()
# Scoped fixtures
@pytest.fixture(scope="module")
def expensive_resource():
return load_heavy_thing()
# scope options: "function" (default), "class", "module", "package", "session"
# Fixture with params
@pytest.fixture(params=["sqlite", "postgres", "mysql"])
def db_engine(request):
return create_engine(request.param)
# Using fixtures
def test_user_name(user):
assert user["name"] == "Alice"
# Basic parametrize
@pytest.mark.parametrize("input,expected", [
("hello", 5),
("", 0),
("world", 5),
])
def test_string_length(input, expected):
assert len(input) == expected
# Multiple parameters
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_combinations(x, y):
pass # Runs 4 times: (0,2), (0,3), (1,2), (1,3)
# With IDs
@pytest.mark.parametrize("input,expected", [
pytest.param("admin", True, id="admin-user"),
pytest.param("guest", False, id="guest-user"),
])
def test_is_admin(input, expected):
assert is_admin(input) == expected
from unittest.mock import Mock, patch, MagicMock
# patch decorator
@patch("myapp.services.send_email")
def test_registration(mock_send):
register_user("[email protected]")
mock_send.assert_called_once_with("[email protected]", subject="Welcome")
# patch as context manager
def test_api_call():
with patch("myapp.client.requests.get") as mock_get:
mock_get.return_value.json.return_value = {"status": "ok"}
result = fetch_status()
assert result == "ok"
# Mock fixture (pytest-mock)
def test_with_mocker(mocker):
mock_db = mocker.patch("myapp.db.query")
mock_db.return_value = [{"id": 1}]
result = get_users()
assert len(result) == 1
# Side effects
mock_func = Mock(side_effect=ValueError("boom"))
mock_func = Mock(side_effect=[1, 2, 3]) # Returns sequentially
mock_func = Mock(side_effect=lambda x: x * 2)
# Spec mocking (catches attribute errors)
mock_obj = Mock(spec=MyClass)
# Skip
@pytest.mark.skip(reason="Not implemented yet")
def test_future_feature():
pass
# Skip conditionally
@pytest.mark.skipif(sys.platform == "win32", reason="Unix only")
def test_unix_permissions():
pass
# Expected failure
@pytest.mark.xfail(reason="Known bug #123")
def test_known_bug():
pass
# Custom markers
@pytest.mark.slow
def test_heavy_computation():
pass
# Run by marker: pytest -m slow
# Run excluding: pytest -m "not slow"
# Register markers in pytest.ini or pyproject.toml
# [tool.pytest.ini_options]
# markers = ["slow: marks tests as slow"]
# Basic
assert result == expected
assert item in collection
assert value is None
# Exception testing
with pytest.raises(ValueError):
int("not_a_number")
with pytest.raises(ValueError, match="invalid literal"):
int("not_a_number")
# Approximate
assert 0.1 + 0.2 == pytest.approx(0.3)
assert result == pytest.approx(expected, rel=1e-3)
# Warnings
with pytest.warns(DeprecationWarning):
deprecated_function()
# Install
pip install pytest-cov
# Run with coverage
pytest --cov=myapp
pytest --cov=myapp --cov-report=html
pytest --cov=myapp --cov-report=term-missing
pytest --cov=myapp --cov-branch # Branch coverage
# Minimum threshold
pytest --cov=myapp --cov-fail-under=80
# tests/conftest.py - Shared fixtures available to all tests
import pytest
@pytest.fixture
def app():
"""Create test application."""
app = create_app(testing=True)
yield app
@pytest.fixture
def client(app):
"""Create test client."""
return app.test_client()
@pytest.fixture
def auth_headers():
"""Create auth headers."""
token = create_test_token()
return {"Authorization": f"Bearer {token}"}
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "-v --tb=short --strict-markers"
markers = [
"slow: marks tests as slow",
"integration: integration tests",
]
filterwarnings = [
"ignore::DeprecationWarning",
]
For advanced patterns, plugins, and async testing: references/patterns.md
tools
Parallel execution with xargs, GNU parallel, and batch processing patterns. Use when user mentions "xargs", "parallel", "batch processing", "run in parallel", "parallel execution", "process list of files", "bulk operations", "concurrent commands", "map over files", or running commands on multiple inputs.
development
WebSocket implementation for real-time bidirectional communication. Use when user mentions "websocket", "ws://", "wss://", "real-time", "live updates", "chat application", "socket.io", "Server-Sent Events", "SSE", "push notifications", "live data", "streaming data", "bidirectional communication", "websocket server", "reconnection", or building real-time features.
tools
Frontend bundler configuration for Webpack and Vite. Use when user mentions "webpack", "vite", "bundler", "vite config", "webpack config", "code splitting", "tree shaking", "hot module replacement", "HMR", "build optimization", "bundle size", "chunk splitting", "loader", "plugin", "esbuild", "rollup", "dev server", or configuring JavaScript build tools.
tools
VS Code configuration, extensions, keybindings, and workspace optimization. Use when user mentions "vscode", "vs code", "vscode settings", "vscode extensions", "keybindings", "code editor", "workspace settings", "settings.json", "launch.json", "tasks.json", "vscode snippets", "devcontainer", "remote development", or customizing their VS Code setup.