skills/pytest-python/SKILL.md
Comprehensive pytest testing skill for Python projects. Write efficient, maintainable tests with fixtures, parametrization, markers, mocking, and assertions. Use when: (1) Writing new tests for Python code, (2) Setting up pytest in a project, (3) Creating fixtures for test dependencies, (4) Parametrizing tests for multiple inputs, (5) Mocking/patching with monkeypatch, (6) Debugging test failures, (7) Organizing test suites with markers, (8) Any Python testing task.
npx skillsauth add alijilani-dev/claude pytest-pythonInstall 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.
Pytest auto-discovers tests matching:
test_*.py or *_test.pytest_* prefixTest* prefix (no __init__)pytest # Run all tests
pytest test_mod.py # Single module
pytest tests/ # Directory
pytest -k "name" # By keyword
pytest -m slow # By marker
pytest test_mod.py::test_func # Specific test
pytest --durations=10 # Show slowest tests
Fixtures provide reusable test dependencies.
import pytest
@pytest.fixture
def sample_data():
return {"key": "value"}
def test_example(sample_data):
assert sample_data["key"] == "value"
@pytest.fixture(scope="function") # Default: per test
@pytest.fixture(scope="class") # Per test class
@pytest.fixture(scope="module") # Per module
@pytest.fixture(scope="session") # Entire session
@pytest.fixture
def db_connection():
conn = create_connection()
yield conn
conn.close() # Cleanup after test
@pytest.fixture
def make_user():
def _make_user(name, role="user"):
return {"name": name, "role": role}
return _make_user
def test_users(make_user):
admin = make_user("Alice", role="admin")
user = make_user("Bob")
@pytest.fixture(params=["mysql", "postgres", "sqlite"])
def database(request):
return create_db(request.param)
Run tests with multiple inputs.
@pytest.mark.parametrize("input,expected", [
(1, 2),
(2, 4),
(3, 6),
])
def test_double(input, expected):
assert input * 2 == expected
@pytest.mark.parametrize("x", [1, 2])
@pytest.mark.parametrize("y", [10, 20])
def test_multiply(x, y): # Runs 4 combinations
assert x * y > 0
@pytest.mark.parametrize("input,expected", [
(1, 1),
pytest.param(0, 1, marks=pytest.mark.xfail),
])
def test_factorial(input, expected):
assert factorial(input) == expected
@pytest.mark.skip(reason="Not implemented")
def test_feature(): ...
@pytest.mark.skipif(sys.platform == "win32", reason="Unix only")
def test_unix(): ...
@pytest.mark.xfail(reason="Known bug")
def test_buggy(): ...
Register in pytest.ini or pyproject.toml:
[pytest]
markers =
slow: marks tests as slow
integration: integration tests
@pytest.mark.slow
def test_slow_operation(): ...
Run: pytest -m slow or pytest -m "not slow"
assert value == expected
assert value != other
assert value is None
assert value is not None
assert value in collection
assert isinstance(obj, MyClass)
assert 0.1 + 0.2 == pytest.approx(0.3)
assert result == pytest.approx(expected, rel=1e-3)
def test_raises():
with pytest.raises(ValueError):
int("invalid")
def test_raises_with_match():
with pytest.raises(ValueError, match=r"invalid.*"):
raise ValueError("invalid input")
def test_raises_inspect():
with pytest.raises(ValueError) as exc_info:
raise ValueError("test error")
assert "test" in str(exc_info.value)
def test_api_call(monkeypatch):
def mock_get(*args, **kwargs):
return {"status": "ok"}
monkeypatch.setattr("mymodule.api.get", mock_get)
result = mymodule.fetch_data()
assert result["status"] == "ok"
def test_with_env(monkeypatch):
monkeypatch.setenv("API_KEY", "test-key")
assert os.environ["API_KEY"] == "test-key"
def test_without_env(monkeypatch):
monkeypatch.delenv("API_KEY", raising=False)
def test_config(monkeypatch):
monkeypatch.setitem(app.config, "DEBUG", True)
| Fixture | Purpose |
|---------|---------|
| tmp_path | Temporary directory (pathlib.Path) |
| tmp_path_factory | Session-scoped temp directories |
| capsys | Capture stdout/stderr |
| caplog | Capture log messages |
| monkeypatch | Dynamic patching |
| request | Fixture/test metadata |
def test_output(capsys):
print("hello")
captured = capsys.readouterr()
assert captured.out == "hello\n"
def test_logging(caplog):
import logging
logging.warning("test warning")
assert "test warning" in caplog.text
def test_temp_file(tmp_path):
file = tmp_path / "test.txt"
file.write_text("content")
assert file.read_text() == "content"
Recommended layout:
project/
├── pyproject.toml
├── src/
│ └── mypackage/
│ ├── __init__.py
│ └── module.py
└── tests/
├── conftest.py # Shared fixtures
├── test_module.py
└── unit/
└── test_specific.py
Shared fixtures available to all tests in directory:
# tests/conftest.py
import pytest
@pytest.fixture
def app():
return create_app(testing=True)
@pytest.fixture
def client(app):
return app.test_client()
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "-v --strict-markers"
markers = [
"slow: marks tests as slow",
"integration: integration tests",
]
filterwarnings = [
"ignore::DeprecationWarning",
]
test_user_creation_with_invalid_email_raises_error@pytest.mark.slowdata-ai
Orchestrate complex tasks by delegating work to parallel subagent teams, preserving the main context window and preventing auto-compact. This skill should be used when users ask to apply subagent-teams, when performing complex multi-step tasks, when context window is getting large, or when independent subtasks can run in parallel.
development
Generate new Claude Code skills with proper structure and standards. Use when the user requests skill creation, wants to generate a new skill, or mentions creating custom Claude Code functionality. Activated by phrases like "create a skill", "generate a skill", "make a new skill", or "build a skill for".
testing
Generate comprehensive educational quizzes based on Bloom's Taxonomy methodology (Remember, Understand, Apply, Analyze, Evaluate, Create). Creates structured True/False quizzes with detailed answer keys and explanations. Use when user requests quiz generation, assessment creation, test materials, practice questions, mentions Bloom's Taxonomy, or provides educational topics for quiz creation. Activates for study topics, course materials, reference files (.md, .txt, .pdf), or educational content requiring systematic assessment.
content-media
Generate comprehensive educational notes using Bloom's Taxonomy methodology. Creates structured learning materials with summaries, practice questions, and visual diagrams. Use when user requests notes generation, study materials, learning resources, mentions Bloom's Taxonomy, or provides topics for educational note-taking. Activates for .md files, study topics, course materials, or educational content creation.