agentsclimarketplace

Python testing

Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/python-testing

When to activate: pytest, TDD, test fixtures, parametrize, async tests, coverage, mocking, hypothesisFrom its SKILL.md

Install
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill python-testing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

4.0 KB, 912 tokens by cl100k_base, as published. Nobody here has run it

Python Testing Patterns

pytest Setup

# pyproject.toml
[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
addopts = ["--strict-markers", "-ra"]

[tool.coverage.run]
source = ["app"]
omit = ["tests/*", "*/migrations/*"]

[tool.coverage.report]
fail_under = 80

Fixture Patterns

import pytest
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from httpx import AsyncClient, ASGITransport

# Scope: session for expensive setup, function for isolation
@pytest.fixture(scope="session")
async def engine():
    engine = create_async_engine("postgresql+asyncpg://test:test@localhost/test_db")
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    yield engine
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.drop_all)

@pytest.fixture
async def db(engine) -> AsyncGenerator[AsyncSession, None]:
    async with AsyncSession(engine) as session:
        yield session
        await session.rollback()  # isolation between tests

@pytest.fixture
async def client(app) -> AsyncGenerator[AsyncClient, None]:
    async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as ac:
        yield ac

# Factory fixtures
@pytest.fixture
def user_factory(db):
    async def _create(**kwargs) -> User:
        defaults = {"email": "[email protected]", "name": "Test User"}
        return await user_service.create(db, {**defaults, **kwargs})
    return _create

Parametrize Patterns

@pytest.mark.parametrize("email,expected", [
    ("[email protected]", True),
    ("invalid-email", False),
    ("", False),
    ("[email protected]", True),
])
def test_email_validation(email: str, expected: bool) -> None:
    assert is_valid_email(email) == expected

# Parametrize with IDs for readable output
@pytest.mark.parametrize("status_code,expected_error", [
    pytest.param(400, "bad_request", id="bad-request"),
    pytest.param(404, "not_found", id="not-found"),
    pytest.param(422, "validation_error", id="validation"),
], ids=...)

Async Tests

# asyncio_mode = "auto" in pyproject.toml means no @pytest.mark.asyncio needed

async def test_create_user(client: AsyncClient, db: AsyncSession) -> None:
    response = await client.post("/api/v1/users", json={
        "email": "[email protected]",
        "password": "securepass123",
        "name": "New User",
    })
    assert response.status_code == 201
    data = response.json()
    assert data["email"] == "[email protected]"
    assert "password" not in data  # PII not leaked

Mocking Patterns

from unittest.mock import AsyncMock, patch, MagicMock

# Patch at the usage site, not the definition site
async def test_sends_email_on_signup(client: AsyncClient) -> None:
    with patch("app.services.email.send_welcome_email", new_callable=AsyncMock) as mock_email:
        response = await client.post("/api/v1/users", json={...})
        assert response.status_code == 201
        mock_email.assert_called_once_with(email="[email protected]")

# Use respx for HTTP mocking in async context
import respx
import httpx

@respx.mock
async def test_external_api_call() -> None:
    respx.get("https://api.example.com/data").mock(
        return_value=httpx.Response(200, json={"value": 42})
    )
    result = await fetch_external_data()
    assert result == 42

Property-Based Tests

from hypothesis import given, strategies as st

@given(
    email=st.emails(),
    name=st.text(min_size=1, max_size=100),
)
def test_user_creation_never_raises_for_valid_input(email: str, name: str) -> None:
    user = UserCreate(email=email, name=name, password="valid123")
    assert user.email == email

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,758. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.