agentleFS
quruhao4800quruhao4800/agent-workflow/skills/testing/python-testing/SKILL.md

python-testing

Skill1 starsChanged 6 months agoMITView on GitHub

Python testing patterns with pytest: test structure, fixtures, mocking, layered test strategy, and coverage. Use when writing tests for Python projects.

53 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use django-verification, project-guidelines-example and 9 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • mstuder-slalomSkill

    django-verification

    Verification loop for Django projects: migrations, linting, tests with coverage, security scans, and deployment readiness checks before release or PR.

    Also in 9 projects that use this

  • HABUBUSSSkill

    project-guidelines-example

    Also in 8 projects that use this

  • AshfaqbsSkill

    springboot-tdd

    Test-driven development for Spring Boot using JUnit 5, Mockito, MockMvc, Testcontainers, and JaCoCo. Use when adding features, fixing bugs, or refactoring.

    Also in 7 projects that use this

  • mstuder-slalomSkill

    springboot-security

    Spring Security best practices for authn/authz, validation, CSRF, secrets, headers, rate limiting, and dependency security in Java Spring Boot services.

    Also in 8 projects that use this

  • nek1987Skill

    postgres-patterns

    PostgreSQL patterns for reviewing migrations and writing efficient queries. Use when reviewing Alembic migrations, optimizing queries, or debugging database issues.

    Also in 15 projects that use this

  • yanhaoluo0Skill

    java-coding-standards

    阿里巴巴Java开发手册编程规约,包含命名风格、常量定义、代码格式、OOP规约、日期时间、集合处理、并发处理、控制语句、注释规约等。Use when writing Java code, reviewing code, or following Alibaba Java coding standards.

    Also in 7 projects that use this

  • +2 more from mstuder-slalom

The file

We split this skill into the rules it gives an agent

5 rules. 0 are common, 1 is distinctive, and 4 are very specific to this project.

  • 0

    Common

    Most of the 48 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use agent-workflow:python-tdd-guide for step-by-step TDD guidance during implementation.

    line 17
  2. Very specific:

    Run all tests: pytest — Run single file: pytest tests/unit/test_user_service.py

    line 39
  3. Distinctive:

    Default to the narrowest layer that covers the behaviour.

    line 51
  4. Very specific:

    Prefer unittest.mock.patch as a decorator or context manager.

    line 97
  5. Very specific:

    Use AsyncMock for any coroutine.

    line 124

“Common” is measured: kept by at least 6 in 10 of the 48 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Python Testing Patterns

TDD Workflow for Python

RED     → Write a failing test first (pytest.raises or assertion failure expected)
GREEN   → Write minimal code to make the test pass
REFACTOR → Improve code while keeping tests green
REPEAT  → Continue with next requirement

Use agent-workflow:python-tdd-guide for step-by-step TDD guidance during implementation.


Test Structure

tests/
├── conftest.py          # shared fixtures (session/module/function scope)
├── unit/
│   ├── test_user_service.py
│   └── test_order_service.py
└── integration/
    ├── test_user_api.py
    └── test_order_api.py

Naming rules:

  • Files: test_<module>.py
  • Functions: test_<behaviour>_<condition> — e.g. test_get_user_not_found
  • Classes (optional grouping): class TestUserService:

Run all tests: pytest — Run single file: pytest tests/unit/test_user_service.py


Test Layering

LayerToolScopeWhen to use
Unitpytest + unittest.mockSingle function / class in isolationService logic, domain rules, utilities
APIFastAPI TestClientRouter + handler (no real DB)HTTP status codes, request validation, response shape
Integrationpytest + real DB/RedisFull stack, real infrastructureCritical flows, cross-service interactions

Default to the narrowest layer that covers the behaviour. Reserve integration tests for flows that cannot be verified in isolation.


Fixtures

Define shared state in conftest.py. Choose the narrowest scope that works.

# tests/conftest.py
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from myapp.main import app
from myapp.database import Base, get_db

@pytest.fixture(scope="session")
def db_engine():
    engine = create_engine("sqlite:///:memory:")
    Base.metadata.create_all(engine)
    yield engine
    Base.metadata.drop_all(engine)

@pytest.fixture
def db_session(db_engine):
    Session = sessionmaker(bind=db_engine)
    session = Session()
    yield session
    session.rollback()
    session.close()

@pytest.fixture
def client(db_session):
    app.dependency_overrides[get_db] = lambda: db_session
    with TestClient(app) as c:
        yield c
    app.dependency_overrides.clear()

Scope guide: session for expensive setup (DB engine, containers), function (default) for anything that mutates state.


Mocking

Prefer unittest.mock.patch as a decorator or context manager. Use pytest-mock's mocker fixture as an alternative.

from unittest.mock import patch, MagicMock, AsyncMock

# Patch at the import location of the caller, not the definition
def test_send_notification_called(user_service):
    with patch("myapp.services.user.notification_client.send") as mock_send:
        user_service.activate(user_id=1)
        mock_send.assert_called_once_with(user_id=1, event="activated")

# Async mock for coroutines
async def test_fetch_user(user_service):
    mock_repo = AsyncMock()
    mock_repo.get_by_id.return_value = User(id=1, name="alice")
    user_service.repo = mock_repo

    result = await user_service.get(1)
    assert result.name == "alice"

# pytest-mock alternative
def test_send_notification_mocker(mocker, user_service):
    mock_send = mocker.patch("myapp.services.user.notification_client.send")
    user_service.activate(user_id=1)
    mock_send.assert_called_once()

Use AsyncMock for any coroutine. Use MagicMock for synchronous callables.


Coverage

# Run with coverage
pytest --cov=src --cov-report=term-missing

# Generate HTML report
pytest --cov=src --cov-report=html
# Open: htmlcov/index.html

Target: overall ≥ 80%. Focus on service and business logic layers. Coverage does not substitute for meaningful assertions — a test that calls code without asserting anything inflates coverage without value.


Anti-patterns

Anti-patternProblemFix
assert True or empty test bodyNo coverage value; passes triviallyWrite a real assertion on the return value or side effect
Mocking the unit under testTests the mock, not the codeOnly mock dependencies, never the class being tested
except Exception: pass inside a testHides failures; test always passesLet exceptions propagate, or use pytest.raises()
Shared mutable state between testsOrder-dependent, flaky testsUse function-scoped fixtures or reset state in setup
Integration test for every caseSlow suite, fragile setupCover happy path in integration; edge cases in unit
Test names like test1, test_funcUnreadable failure outputUse descriptive names: test_get_user_returns_404_when_not_found

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.