
Pytest Mastery
- 1 installs
- 404 repo stars
- Updated August 5, 2026
- aiskillstore/marketplace
pytest-mastery is a Claude Code skill for Python testing with pytest using the uv package manager, covering fixtures, parametrization, coverage, and FastAPI testing.
About
pytest-mastery is a Claude Code skill for Python testing with pytest using the uv package manager. It covers test discovery conventions, fixtures and scopes, parametrization, markers, coverage reports, pyproject.toml configuration, and FastAPI testing. A developer uses it to run tests, write test files and fixtures, generate coverage, and debug failing tests.
- Python testing with pytest run through the uv package manager
- Covers fixtures, parametrization, markers, and coverage reports
- Includes FastAPI testing patterns and a bundled run_tests.py script
Pytest Mastery by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,750 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
pytest-mastery capabilities & compatibility
Free; a testing-pattern skill with no external service
- Capabilities
- testing · code coverage · api testing
- Use cases
- testing · api development
- Pricing
- Free
What pytest-mastery says it does
Python testing with pytest using uv package manager.
pytest automatically discovers tests following these conventions:
npx skills add https://github.com/aiskillstore/marketplace --skill pytest-masteryAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 404 |
| Last updated | August 5, 2026 |
| Repository | aiskillstore/marketplace ↗ |
What it does
Write and run Python pytest suites with fixtures, parametrization, coverage, and FastAPI testing.
Who is it for?
Writing, running, and configuring pytest suites for Python and FastAPI projects
Skip if: Non-Python testing or test frameworks other than pytest
When should I use this skill?
Running Python tests, writing test files, setting up fixtures, generating coverage, or testing FastAPI
What you get
Well-structured pytest suites with fixtures, coverage thresholds, and FastAPI test patterns.
- pytest test files and fixtures
- coverage reports
- pyproject.toml test config
By the numbers
- lists 12 common pytest CLI options
- coverage example uses --cov-fail-under=80
Files
pytest Testing with uv
Quick Reference
# Run all tests
uv run pytest
# Run with verbose output
uv run pytest -v
# Run specific file
uv run pytest tests/test_example.py
# Run specific test function
uv run pytest tests/test_example.py::test_function_name
# Run tests matching pattern
uv run pytest -k "pattern"
# Run with coverage
uv run pytest --cov=src --cov-report=htmlInstallation
# Add pytest as dev dependency
uv add --dev pytest
# Add coverage support
uv add --dev pytest-cov
# Add async support (for FastAPI)
uv add --dev pytest-asyncio httpxTest Discovery
pytest automatically discovers tests following these conventions:
- Files:
test_*.pyor*_test.py - Functions:
test_* - Classes:
Test*(no__init__method) - Methods:
test_*insideTest*classes
Standard project structure:
project/
├── src/
│ └── myapp/
├── tests/
│ ├── __init__.py
│ ├── conftest.py # Shared fixtures
│ ├── test_unit.py
│ └── integration/
│ └── test_api.py
└── pyproject.tomlFixtures
Fixtures provide reusable test setup/teardown:
import pytest
@pytest.fixture
def sample_user():
return {"id": 1, "name": "Test User"}
@pytest.fixture
def db_connection():
conn = create_connection()
yield conn # Test runs here
conn.close() # Teardown
def test_user_name(sample_user):
assert sample_user["name"] == "Test User"Fixture Scopes
@pytest.fixture(scope="function") # Default: new instance per test
@pytest.fixture(scope="class") # Once per test class
@pytest.fixture(scope="module") # Once per module
@pytest.fixture(scope="session") # Once per test sessionShared Fixtures (conftest.py)
Place in tests/conftest.py for automatic availability:
# tests/conftest.py
import pytest
@pytest.fixture
def api_client():
return TestClient(app)Parametrization
Run same test with multiple inputs:
import pytest
@pytest.mark.parametrize("input,expected", [
(1, 2),
(2, 4),
(3, 6),
])
def test_double(input, expected):
assert input * 2 == expected
@pytest.mark.parametrize("value", [None, "", [], {}])
def test_falsy_values(value):
assert not valueCommon Options
| Option | Description |
|---|---|
-v | Verbose output |
-vv | More verbose |
-q | Quiet mode |
-x | Stop on first failure |
--lf | Run last failed tests only |
--ff | Run failures first |
-k "expr" | Filter by name expression |
-m "mark" | Run marked tests only |
--tb=short | Shorter traceback |
--tb=no | No traceback |
-s | Show print statements |
--durations=10 | Show 10 slowest tests |
-n auto | Parallel execution (pytest-xdist) |
Coverage Reports
# Terminal report
uv run pytest --cov=src
# HTML report (creates htmlcov/)
uv run pytest --cov=src --cov-report=html
# With minimum threshold (fails if below)
uv run pytest --cov=src --cov-fail-under=80
# Multiple report formats
uv run pytest --cov=src --cov-report=term --cov-report=xmlMarkers
import pytest
@pytest.mark.slow
def test_slow_operation():
...
@pytest.mark.skip(reason="Not implemented")
def test_future_feature():
...
@pytest.mark.skipif(condition, reason="...")
def test_conditional():
...
@pytest.mark.xfail(reason="Known bug")
def test_known_failure():
...Run by marker:
uv run pytest -m "not slow"
uv run pytest -m "integration"pyproject.toml Configuration
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "-v --tb=short"
markers = [
"slow: marks tests as slow",
"integration: integration tests",
]
[tool.coverage.run]
source = ["src"]
omit = ["tests/*", "*/__init__.py"]
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"if TYPE_CHECKING:",
]FastAPI Testing
See references/fastapi-testing.md for comprehensive FastAPI testing patterns including:
- TestClient setup
- Async testing with httpx
- Database fixture patterns
- Dependency overrides
- Authentication testing
Debugging Failed Tests
# Run with full traceback
uv run pytest --tb=long
# Drop into debugger on failure
uv run pytest --pdb
# Show local variables in traceback
uv run pytest -l
# Run only previously failed
uv run pytest --lfFastAPI Testing Patterns
TestClient Setup
# tests/conftest.py
import pytest
from fastapi.testclient import TestClient
from myapp.main import app
@pytest.fixture
def client():
return TestClient(app)Basic test:
def test_read_root(client):
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Hello World"}Async Testing with httpx
For async endpoints, use pytest-asyncio and httpx:
# tests/conftest.py
import pytest
from httpx import AsyncClient, ASGITransport
from myapp.main import app
@pytest.fixture
async def async_client():
async with AsyncClient(
transport=ASGITransport(app=app),
base_url="http://test"
) as client:
yield clientimport pytest
@pytest.mark.asyncio
async def test_async_endpoint(async_client):
response = await async_client.get("/async-endpoint")
assert response.status_code == 200Configure in pyproject.toml:
[tool.pytest.ini_options]
asyncio_mode = "auto"Database Testing
SQLAlchemy with Test Database
# tests/conftest.py
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from myapp.database import Base, get_db
from myapp.main import app
from fastapi.testclient import TestClient
TEST_DATABASE_URL = "sqlite:///./test.db"
engine = create_engine(TEST_DATABASE_URL, connect_args={"check_same_thread": False})
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
@pytest.fixture(scope="function")
def db():
Base.metadata.create_all(bind=engine)
db = TestingSessionLocal()
try:
yield db
finally:
db.close()
Base.metadata.drop_all(bind=engine)
@pytest.fixture
def client(db):
def override_get_db():
try:
yield db
finally:
pass
app.dependency_overrides[get_db] = override_get_db
with TestClient(app) as c:
yield c
app.dependency_overrides.clear()Dependency Overrides
Override any FastAPI dependency for testing:
# myapp/dependencies.py
async def get_current_user():
# Real auth logic
...
# tests/conftest.py
from myapp.dependencies import get_current_user
from myapp.main import app
@pytest.fixture
def authenticated_client():
def mock_current_user():
return {"id": 1, "username": "testuser", "role": "admin"}
app.dependency_overrides[get_current_user] = mock_current_user
with TestClient(app) as client:
yield client
app.dependency_overrides.clear()Testing Authentication
JWT Token Testing
@pytest.fixture
def auth_headers():
# Create test token
token = create_access_token(data={"sub": "testuser"})
return {"Authorization": f"Bearer {token}"}
def test_protected_endpoint(client, auth_headers):
response = client.get("/protected", headers=auth_headers)
assert response.status_code == 200OAuth2 Password Flow
def test_login(client):
response = client.post(
"/token",
data={"username": "testuser", "password": "testpass"},
headers={"Content-Type": "application/x-www-form-urlencoded"}
)
assert response.status_code == 200
assert "access_token" in response.json()Testing Request/Response Models
from pydantic import ValidationError
from myapp.schemas import UserCreate
def test_user_schema_valid():
user = UserCreate(email="test@example.com", password="secure123")
assert user.email == "test@example.com"
def test_user_schema_invalid():
with pytest.raises(ValidationError):
UserCreate(email="invalid", password="")Testing File Uploads
def test_upload_file(client):
files = {"file": ("test.txt", b"file content", "text/plain")}
response = client.post("/upload", files=files)
assert response.status_code == 200Testing WebSockets
def test_websocket(client):
with client.websocket_connect("/ws") as websocket:
websocket.send_text("hello")
data = websocket.receive_text()
assert data == "Message: hello"Testing Background Tasks
from unittest.mock import patch
def test_with_background_task(client):
with patch("myapp.tasks.send_email") as mock_send:
response = client.post("/register", json={"email": "test@example.com"})
assert response.status_code == 201
mock_send.assert_called_once()Testing Error Responses
def test_not_found(client):
response = client.get("/items/99999")
assert response.status_code == 404
assert response.json()["detail"] == "Item not found"
def test_validation_error(client):
response = client.post("/items", json={"price": "invalid"})
assert response.status_code == 422Testing with Lifespan Events
@pytest.fixture
def client():
# TestClient handles lifespan automatically
with TestClient(app) as client:
yield clientMocking External Services
from unittest.mock import AsyncMock, patch
@pytest.mark.asyncio
async def test_external_api_call(async_client):
mock_response = {"data": "mocked"}
with patch("myapp.services.external_api.fetch", new_callable=AsyncMock) as mock:
mock.return_value = mock_response
response = await async_client.get("/external-data")
assert response.status_code == 200
mock.assert_called_once()Factory Pattern for Test Data
# tests/factories.py
from myapp.models import User
class UserFactory:
@staticmethod
def create(db, **overrides):
defaults = {
"email": "test@example.com",
"hashed_password": "hashed",
"is_active": True
}
defaults.update(overrides)
user = User(**defaults)
db.add(user)
db.commit()
db.refresh(user)
return user
# In tests
def test_get_user(client, db):
user = UserFactory.create(db, email="specific@example.com")
response = client.get(f"/users/{user.id}")
assert response.json()["email"] == "specific@example.com"#!/usr/bin/env python3
"""
pytest runner script with common configurations.
Usage: uv run scripts/run_tests.py [mode] [additional pytest args]
Modes:
quick - Fast tests only, stop on first failure
full - All tests with verbose output
coverage - Full tests with coverage report
failed - Re-run only failed tests
watch - Run tests matching a pattern (pass pattern as next arg)
"""
import subprocess
import sys
from pathlib import Path
def get_project_root() -> Path:
"""Find project root by looking for pyproject.toml."""
current = Path.cwd()
for parent in [current] + list(current.parents):
if (parent / "pyproject.toml").exists():
return parent
return current
def run_pytest(args: list[str]) -> int:
"""Run pytest with uv."""
cmd = ["uv", "run", "pytest"] + args
print(f"Running: {' '.join(cmd)}")
return subprocess.call(cmd, cwd=get_project_root())
def main():
args = sys.argv[1:]
if not args:
# Default: run all tests with verbose output
return run_pytest(["-v"])
mode = args[0]
extra_args = args[1:]
modes = {
"quick": ["-v", "-x", "--tb=short", "-m", "not slow"],
"full": ["-v", "--tb=short"],
"coverage": [
"-v",
"--cov=src",
"--cov-report=term-missing",
"--cov-report=html",
],
"failed": ["--lf", "-v"],
"watch": ["-v", "-k"] + (extra_args[:1] if extra_args else [""]),
}
if mode in modes:
pytest_args = modes[mode]
if mode != "watch":
pytest_args.extend(extra_args)
else:
pytest_args.extend(extra_args[1:])
return run_pytest(pytest_args)
# If mode is not recognized, pass all args directly to pytest
return run_pytest(args)
if __name__ == "__main__":
sys.exit(main())
{
"schema_version": "2.0",
"meta": {
"generated_at": "2026-01-16T16:04:24.930Z",
"slug": "abdullahmalik17-pytest-mastery",
"source_url": "https://github.com/AbdullahMalik17/Cloud-Native-AI/tree/main/.claude/skills/pytest-mastery",
"source_ref": "main",
"model": "claude",
"analysis_version": "3.0.0",
"source_type": "community",
"content_hash": "28d0c39ef515a0fc9a3740a7421a720c45812c85afb0b6df61cabb0945f7cc42",
"tree_hash": "5864c983c69af6d6021b5051623ee7e62c3e1a3aad2740752d09a3b3095b1aea"
},
"skill": {
"name": "pytest-mastery",
"description": "Python testing with pytest using uv package manager. Use when: (1) Running Python tests, (2) Writing test files or test functions, (3) Setting up fixtures, (4) Parametrizing tests, (5) Generating coverage reports, (6) Testing FastAPI applications, (7) Debugging test failures, (8) Configuring pytest options. Triggers: \"run tests\", \"write tests\", \"test coverage\", \"pytest\", \"unit test\", \"integration test\", \"test FastAPI\".\n",
"summary": "Python testing with pytest using uv package manager. Use when: (1) Running Python tests, (2) Writing...",
"icon": "🧪",
"version": "1.0.0",
"author": "AbdullahMalik17",
"license": "MIT",
"category": "coding",
"tags": [
"pytest",
"testing",
"python",
"uv",
"fastapi"
],
"supported_tools": [
"claude",
"codex",
"claude-code"
],
"risk_factors": [
"scripts",
"external_commands"
]
},
"security_audit": {
"risk_level": "safe",
"is_blocked": false,
"safe_to_publish": true,
"summary": "This is a legitimate testing documentation skill. Static analyzer flagged 110 issues, but all are false positives: markdown code fences were mistaken for shell backticks, and keywords in test examples triggered crypto/network patterns. The actual code is a pytest runner that executes tests locally with hardcoded arguments.",
"risk_factor_evidence": [
{
"factor": "scripts",
"evidence": [
{
"file": "scripts/run_tests.py",
"line_start": 1,
"line_end": 72
}
]
},
{
"factor": "external_commands",
"evidence": [
{
"file": "scripts/run_tests.py",
"line_start": 28,
"line_end": 32
}
]
}
],
"critical_findings": [],
"high_findings": [],
"medium_findings": [],
"low_findings": [],
"dangerous_patterns": [],
"files_scanned": 4,
"total_lines": 801,
"audit_model": "claude",
"audited_at": "2026-01-16T16:04:24.930Z"
},
"content": {
"user_title": "Write and run Python tests with pytest",
"value_statement": "Writing tests for Python applications can be confusing without guidance on fixtures, parametrization, and coverage tools. This skill provides ready-to-use pytest patterns including FastAPI testing, fixtures, and coverage reporting.",
"seo_keywords": [
"pytest testing",
"Python testing",
"pytest fixtures",
"pytest parametrization",
"test coverage",
"uv package manager",
"FastAPI testing",
"Claude Code testing",
"unit tests",
"integration tests"
],
"actual_capabilities": [
"Run pytest tests with uv package manager",
"Create and use pytest fixtures with different scopes",
"Parametrize tests with multiple inputs",
"Generate coverage reports in multiple formats",
"Test FastAPI applications with TestClient and httpx",
"Debug test failures with pytest options"
],
"limitations": [
"Does not generate test code from specifications",
"Does not integrate with CI/CD pipelines",
"Does not perform snapshot testing"
],
"use_cases": [
{
"target_user": "Python developers",
"title": "Add tests to Python projects",
"description": "Set up pytest with fixtures and parametrization for Python libraries and applications"
},
{
"target_user": "FastAPI developers",
"title": "Test FastAPI endpoints",
"description": "Write integration tests for FastAPI endpoints using TestClient and async testing patterns"
},
{
"target_user": "QA engineers",
"title": "Generate coverage reports",
"description": "Run tests with coverage analysis and generate HTML or XML reports for CI/CD pipelines"
}
],
"prompt_templates": [
{
"title": "Run basic tests",
"scenario": "Running pytest with uv",
"prompt": "Run all pytest tests with uv package manager"
},
{
"title": "Create fixture",
"scenario": "Setting up test fixtures",
"prompt": "Create a pytest fixture for database connection with proper teardown"
},
{
"title": "Parametrize tests",
"scenario": "Running same test with multiple inputs",
"prompt": "Write a parametrized test that checks multiple input combinations"
},
{
"title": "Coverage report",
"scenario": "Generating test coverage",
"prompt": "Run pytest with coverage and generate an HTML coverage report"
}
],
"output_examples": [
{
"input": "Run pytest tests with coverage",
"output": [
"Running: uv run pytest --cov=src --cov-report=html",
"Coverage report generated in htmlcov/",
"View report: open htmlcov/index.html"
]
},
{
"input": "Create a test fixture for API client",
"output": [
"Created fixture in tests/conftest.py",
"Use @pytest.fixture decorator",
"Scope defaults to function, use scope=\"session\" for shared"
]
},
{
"input": "Write a test that checks multiple inputs",
"output": [
"Use @pytest.mark.parametrize decorator",
"Define test cases as list of tuples",
"pytest runs the test once per input"
]
}
],
"best_practices": [
"Use fixtures for reusable test setup instead of repeating initialization code",
"Run coverage reports regularly to identify untested code paths",
"Use parametrization to test multiple input cases with a single test function"
],
"anti_patterns": [
"Avoid hardcoding test data directly in test functions",
"Do not skip fixture scopes without considering resource usage",
"Avoid mixing unit and integration tests in the same test suite without markers"
],
"faq": [
{
"question": "Which Python versions support pytest?",
"answer": "pytest supports Python 3.8+ and works with uv package manager on all major platforms."
},
{
"question": "What is the maximum test count per run?",
"answer": "pytest runs all discovered tests. For large projects, use markers or parallel execution with pytest-xdist."
},
{
"question": "Does this skill integrate with CI/CD tools?",
"answer": "Commands can be run in any CI/CD pipeline that supports Python and uv. Use --tb=short for cleaner logs."
},
{
"question": "Is test data stored or transmitted?",
"answer": "All tests run locally. Coverage reports are generated locally and never leave the machine."
},
{
"question": "Why are my tests not being discovered?",
"answer": "Ensure files match test_*.py or *_test.py pattern. Functions must start with test_ and classes with Test*."
},
{
"question": "How does this compare to unittest?",
"answer": "pytest offers simpler syntax, powerful fixtures, parametrization, and better reporting compared to Python's built-in unittest."
}
]
},
"file_structure": [
{
"name": "references",
"type": "dir",
"path": "references",
"children": [
{
"name": "fastapi-testing.md",
"type": "file",
"path": "references/fastapi-testing.md",
"lines": 266
}
]
},
{
"name": "scripts",
"type": "dir",
"path": "scripts",
"children": [
{
"name": "run_tests.py",
"type": "file",
"path": "scripts/run_tests.py",
"lines": 72
}
]
},
{
"name": "SKILL.md",
"type": "file",
"path": "SKILL.md",
"lines": 240
}
]
}
Related skills
FAQ
What package manager does pytest-mastery use?
uv - tests run via 'uv run pytest' and dev dependencies are added with 'uv add --dev pytest'.
Does it cover FastAPI?
Yes - references/fastapi-testing.md covers TestClient setup, async testing with httpx, database fixtures, and dependency overrides.