Back to skills
SkillHub ClubWrite Technical DocsFull StackTech WriterTesting

python-testing

Python testing strategy and patterns. Use when designing test strategy, writing tests, or evaluating test coverage. Covers test pyramid, TDD workflow, and pytest patterns.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
0
Hot score
74
Updated
March 20, 2026
Overall rating
C2.5
Composite score
2.5
Best-practice grade
A88.0

Install command

npx @skill-hub/cli install alicoding-nextura-python-testing

Repository

alicoding/nextura

Skill path: .claude/skills/python-testing

Python testing strategy and patterns. Use when designing test strategy, writing tests, or evaluating test coverage. Covers test pyramid, TDD workflow, and pytest patterns.

Open repository

Best for

Primary workflow: Write Technical Docs.

Technical facets: Full Stack, Tech Writer, Testing.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: alicoding.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install python-testing into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/alicoding/nextura before adding python-testing to shared team environments
  • Use python-testing for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: python-testing
scope: python
description: >
  Python testing strategy and patterns. Use when designing test strategy,
  writing tests, or evaluating test coverage. Covers test pyramid,
  TDD workflow, and pytest patterns.
version: 3.0.0
triggers:
  - test strategy
  - what to test
  - test pyramid
  - unit test
  - integration test
  - test coverage

gates:
  pre:
    - "test -d tests/unit"
    - "test -d tests/integration"
  post:
    - "pytest --cov=src --cov-fail-under=80"
---

# Python Testing

Design test strategies that catch bugs without slowing development. Focus on testing behavior, not implementation.

---

## Quick Start

1. **Load coverage thresholds from SSOT**
2. **Follow test pyramid** (70% unit, 20% integration, 10% E2E)
3. **Write test first** (TDD: Red -> Green -> Refactor)
4. **Run pytest with coverage**

---

## Load Standards from SSOT

```bash
# Load coverage thresholds and test requirements
cat data/enterprise/standards/STD-TEST-001.yaml
```

Apply coverage targets from standards.

---

## Test Pyramid

```
        /\          E2E (10%)
       /  \         - Critical user journeys
      /----\        - Slow, few
     /      \
    /--------\      Integration (20%)
   /          \     - Adapter tests
  /------------\    - Real DB/API
 /              \
/----------------\  Unit (70%)
                    - Business logic
                    - Fast, many
```

**For detailed patterns:** See [reference/pyramid.md](reference/pyramid.md)

---

## TDD Workflow

```
RED    -> Write failing test
GREEN  -> Write minimum code to pass
REFACTOR -> Improve code, tests still pass
```

```python
# 1. RED: Write failing test
def test_calculate_discount():
    order = Order(total=Decimal("100.00"))
    assert calculate_discount(order) == Decimal("10.00")

# 2. GREEN: Minimal implementation
def calculate_discount(order: Order) -> Decimal:
    return order.total * Decimal("0.10")

# 3. REFACTOR: Improve while tests pass
```

---

## Test Organization

```
tests/
├── conftest.py           # Shared fixtures
├── unit/                 # Fast, isolated
│   ├── conftest.py
│   └── test_services.py
├── integration/          # With real adapters
│   └── test_database.py
└── e2e/                  # Full system
    └── test_workflows.py
```

---

## STOP GATES

### STOP GATE 1: Pyramid Balanced

**Check:** Does test distribution match pyramid?
**Pass:** Unit > Integration > E2E by count
**Fail:** STOP. Add more unit tests.

### STOP GATE 2: Test First

**Check:** Did I write the test first?
**Pass:** Test exists and fails before implementation
**Fail:** STOP. Write the test first.

### STOP GATE 3: Coverage Threshold

**Check:** Does coverage meet SSOT requirements?
**Pass:** Meets threshold from STD-TEST-001
**Fail:** STOP. Add tests for uncovered code.

### STOP GATE 4: Fast Tests

**Check:** Are unit tests fast?
**Pass:** Unit suite < 30 seconds
**Fail:** STOP. Fix slow tests.

---

## Quick Reference

```
UNIT TEST (70%)
[ ] Business logic
[ ] Validation rules
[ ] Pure functions
[ ] < 10ms each

INTEGRATION TEST (20%)
[ ] Database adapters
[ ] HTTP clients
[ ] File system
[ ] < 1s each

E2E TEST (10%)
[ ] Critical user journeys
[ ] Login/checkout flows
[ ] < 30s each
```

---

## Anti-Patterns

| If you're doing... | STOP. Do this instead... |
|--------------------|--------------------------|
| More E2E than unit | Invert the pyramid |
| Testing implementation | Test behavior |
| 100% coverage goal | Target by component |
| Slow unit tests | Remove I/O, use fakes |
| Hardcoding thresholds | Load from STD-TEST-001 |
| Code before test | Write failing test first |

---

## Reference Files

- [reference/pyramid.md](reference/pyramid.md) - Test pyramid details
- [reference/patterns.md](reference/patterns.md) - Test patterns and fixtures
- [reference/doubles.md](reference/doubles.md) - Mocks, stubs, fakes
- [reference/advanced.md](reference/advanced.md) - Property testing, CI


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### reference/pyramid.md

```markdown
# Test Pyramid Details

## What Each Level Tests

```
UNIT TESTS: Domain Logic
├── Entities and value objects
├── Domain services
├── Business rules
├── Pure functions
└── Input validation

INTEGRATION TESTS: Boundaries
├── Database adapters (real DB)
├── HTTP clients (mocked or real)
├── File system operations
├── Message queue adapters
└── Third-party API clients

E2E TESTS: User Journeys
├── Critical paths (login, checkout)
├── Happy path workflows
├── Multi-step processes
└── UI interactions
```

---

## Unit Tests

**What to test:**
```python
# Business logic
def calculate_discount(order: Order, customer: Customer) -> Decimal:
    if customer.is_premium:
        return order.total * Decimal("0.10")
    return Decimal("0")

# Validation rules
def validate_email(email: str) -> bool:
    return bool(re.match(r"^[\w.-]+@[\w.-]+\.\w+$", email))
```

**What NOT to test:**
- Simple getters/setters
- Data containers (@dataclass)
- Thin wrappers

---

## Integration Tests

```python
def test_user_repository_saves_and_retrieves():
    repo = PostgresUserRepository(connection)
    user = User(id="1", name="Alice")

    repo.save(user)
    retrieved = repo.get("1")

    assert retrieved == user
```

---

## E2E Tests

```python
def test_checkout_flow():
    client.login("[email protected]", "password")
    client.add_to_cart(product_id="123", quantity=2)
    order = client.checkout(payment_method="card")

    assert order.status == "confirmed"
```

| Journey | E2E? | Reason |
|---------|------|--------|
| Login | Yes | Critical |
| Checkout | Yes | Revenue |
| Profile update | No | Unit test |

```

### reference/patterns.md

```markdown
# Test Patterns

## Arrange-Act-Assert

```python
def test_premium_customer_gets_discount():
    # Arrange
    order = Order(total=Decimal("100.00"))
    customer = Customer(is_premium=True)

    # Act
    discount = calculate_discount(order, customer)

    # Assert
    assert discount == Decimal("10.00")
```

---

## Parameterized Tests

```python
@pytest.mark.parametrize("email,expected", [
    ("[email protected]", True),
    ("invalid", False),
    ("@nodomain.com", False),
])
def test_email_validation(email: str, expected: bool):
    assert validate_email(email) == expected
```

---

## Fixtures

```python
# conftest.py
@pytest.fixture
def order_repository() -> OrderRepository:
    return InMemoryOrderRepository()

@pytest.fixture
def order_service(order_repository: OrderRepository) -> OrderService:
    return OrderService(repository=order_repository)

@pytest.fixture
def sample_order() -> Order:
    return Order(id="order-123", total=Decimal("100.00"))
```

---

## Fixture Scopes

```python
@pytest.fixture(scope="function")  # Default: new for each test
def user(): return User()

@pytest.fixture(scope="module")    # Shared within module
def database(): return create_db()

@pytest.fixture(scope="session")   # Shared across all tests
def app(): return create_app()
```

---

## Factory Pattern

```python
class OrderFactory:
    @staticmethod
    def build(
        id: str | None = None,
        total: Decimal = Decimal("100.00"),
    ) -> Order:
        return Order(
            id=id or f"order-{uuid.uuid4().hex[:6]}",
            total=total,
        )

# Usage
def test_discount():
    order = OrderFactory.build(total=Decimal("200.00"))
```

```

### reference/doubles.md

```markdown
# Test Doubles

## Types

| Type | Purpose | Example |
|------|---------|---------|
| **Stub** | Return fixed values | `stub.get() -> User("test")` |
| **Mock** | Verify interactions | `mock.send.assert_called()` |
| **Fake** | Working implementation | In-memory DB |
| **Spy** | Record calls | Log then call real |

---

## Stub

```python
def test_discount_for_premium(stub_customer_service):
    stub_customer_service.is_premium.return_value = True
    discount = calculate_discount(order, stub_customer_service)
    assert discount > 0
```

---

## Mock

```python
def test_email_sent_on_signup(mock_email_service):
    signup(user, mock_email_service)
    mock_email_service.send.assert_called_once_with(
        to=user.email,
        template="welcome"
    )
```

---

## Fake

```python
class InMemoryUserRepository:
    def __init__(self):
        self._users = {}

    def save(self, user: User) -> None:
        self._users[user.id] = user

    def get(self, id: str) -> User:
        return self._users[id]

def test_repository():
    repo = InMemoryUserRepository()  # Fake
    repo.save(user)
    assert repo.get(user.id) == user
```

---

## When to Use Each

```
MOCK when:
├── Testing side effects
├── Verifying interactions
└── External service

FAKE when:
├── Need realistic behavior
├── Stateful operations
└── Multiple tests share setup
```

```

### reference/advanced.md

```markdown
# Advanced Testing

## Property-Based Testing

```python
from hypothesis import given, strategies as st

@given(st.lists(st.integers()))
def test_sort_idempotent(lst):
    assert sorted(sorted(lst)) == sorted(lst)

@given(st.from_type(User))
def test_json_roundtrip(user):
    restored = User.from_json(user.to_json())
    assert restored == user
```

---

## Async Testing

```python
@pytest.mark.asyncio
async def test_async_fetch():
    async with AsyncClient() as client:
        response = await client.get("https://api.example.com")
        assert response.status_code == 200

@pytest.fixture
async def async_client():
    async with AsyncClient(app=app) as client:
        yield client
```

---

## Testcontainers

```python
from testcontainers.postgres import PostgresContainer

@pytest.fixture(scope="session")
def postgres():
    with PostgresContainer("postgres:15") as pg:
        yield pg.get_connection_url()

def test_with_real_db(postgres):
    repo = UserRepository(postgres)
    repo.save(User(id="1", name="Alice"))
```

---

## CI Integration

```yaml
# .github/workflows/test.yml
- name: Run tests
  run: pytest --cov=src --cov-report=xml --cov-fail-under=80

- name: Upload coverage
  uses: codecov/codecov-action@v4
```

---

## Parallel Execution

```bash
# pytest-xdist
pytest -n auto  # All CPUs
pytest -n 4     # 4 workers
```

---

## Coverage Targets

Load from SSOT: `STD-TEST-001.yaml`

Typical targets:
| Component | Target |
|-----------|--------|
| Core/domain | 95%+ |
| Services | 85%+ |
| Adapters | 70%+ |
| CLI | 30%+ |

```