pytest-configuration
Provides Complete pytest configuration: pyproject.toml setup, custom markers registration, test discovery patterns, plugin configuration, environment-specific settings. Includes conftest.py hierarchy, fixture scoping, and coverage configuration. Use when: Setting up pytest in a project, configuring test discovery, creating shared fixtures, setting up coverage reporting, managing test environments, organizing conftest.py files.
What this skill does
# Pytest Configuration
## Purpose
Proper pytest configuration ensures fast test discovery, correct isolation, and consistent behavior across environments. This skill provides production-ready configuration patterns.
## When to Use This Skill
Use when setting up pytest in a project with "configure pytest", "setup test discovery", "create conftest", or "configure coverage".
Do NOT use for writing tests themselves (use layer-specific testing skills), debugging failures (use `test-debug-failures`), or mocking strategies (use `pytest-mocking-strategy`).
## Quick Start
Minimal `pyproject.toml` configuration:
```toml
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
asyncio_mode = "auto" # For async tests
asyncio_default_fixture_loop_scope = "function" # Max isolation
addopts = [
"--strict-markers",
"--cov=app",
"--cov-report=html",
"--cov-fail-under=80",
]
markers = [
"unit: Unit tests (fast, mocked)",
"integration: Integration tests (external services)",
]
```
## Instructions
### Step 1: Configure Test Discovery
```toml
# pyproject.toml
[tool.pytest.ini_options]
# Where pytest looks for tests
testpaths = ["tests"]
# Test file naming pattern
python_files = ["test_*.py", "*_test.py"]
# Test class naming pattern
python_classes = ["Test*"]
# Test function naming pattern
python_functions = ["test_*"]
# Minimum Python version
minversion = "7.0"
```
### Step 2: Configure Async Support
```toml
[tool.pytest.ini_options]
# Auto-detect async tests (no decorator needed)
asyncio_mode = "auto"
# Event loop scope for async tests
# "function": New loop per test (max isolation)
# "module": Shared loop per module (faster)
# "session": Single loop for all tests (fastest)
asyncio_default_fixture_loop_scope = "function"
```
### Step 3: Set Up Custom Markers
```toml
[tool.pytest.ini_options]
markers = [
"unit: Unit tests (fast, fully mocked)",
"integration: Integration tests (external services)",
"e2e: End-to-end tests (full pipeline)",
"slow: Tests that take significant time",
"smoke: Critical path smoke tests",
"skip_ci: Skip in CI environment",
]
# Usage:
# pytest -m unit # Run only unit tests
# pytest -m "not slow" # Exclude slow tests
# pytest -m "unit or integration" # Multiple markers
```
### Step 4: Configure Coverage Reporting
```toml
[tool.pytest.ini_options]
addopts = [
"--strict-markers",
"--strict-config",
"-ra", # All outcomes summary
"--showlocals", # Show local vars in traceback
"--tb=short", # Short traceback format
"--cov=app", # Coverage source
"--cov-report=html", # HTML report
"--cov-report=term-missing", # Terminal with missing lines
"--cov-fail-under=80", # Fail if < 80%
]
# Coverage configuration
[tool.coverage.run]
source = ["app"]
branch = true # Branch coverage
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/venv/*",
"*/.venv/*",
]
[tool.coverage.report]
precision = 2
show_missing = true
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise NotImplementedError",
"if TYPE_CHECKING:",
"if __name__ == .__main__.:",
"@(abc\\.)?abstractmethod",
]
[tool.coverage.html]
directory = "htmlcov"
```
### Step 5: Set Up Logging in Pytest
```toml
[tool.pytest.ini_options]
log_cli = true
log_cli_level = "INFO"
log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s"
log_cli_date_format = "%Y-%m-%d %H:%M:%S"
# Or log to file
log_file = "pytest.log"
log_file_level = "DEBUG"
log_file_format = "%(asctime)s [%(levelname)8s] %(name)s: %(message)s"
```
### Step 6: Create Root conftest.py
```python
# tests/conftest.py - Root-level shared fixtures
from __future__ import annotations
import os
from typing import Generator
import pytest
def pytest_configure(config: pytest.Config) -> None:
"""Configure pytest environment before running tests."""
# Set test environment variables
os.environ["ENVIRONMENT"] = "test"
os.environ["LOG_LEVEL"] = "DEBUG"
@pytest.fixture(scope="session", autouse=True)
def test_environment() -> Generator[None, None, None]:
"""Set up test environment for entire session."""
# Save original environment
original_env = os.environ.copy()
# Configure test environment
os.environ.update({
"SHOPIFY_SHOP_URL": "https://test.myshopify.com",
"SHOPIFY_ACCESS_TOKEN": "test_token_123",
"KAFKA_BOOTSTRAP_SERVERS": "localhost:9092",
"CLICKHOUSE_HOST": "localhost",
"CLICKHOUSE_PORT": "8123",
})
yield
# Restore original environment
os.environ.clear()
os.environ.update(original_env)
```
### Step 7: Create Unit Test Conftest with Fixtures
```python
# tests/unit/conftest.py - Unit test shared fixtures
from __future__ import annotations
from datetime import datetime
from typing import Optional
import pytest
from app.extraction.domain.entities import Order, LineItem
from app.extraction.domain.value_objects import OrderId, ProductId, ProductTitle, Money
# Test data factories
@pytest.fixture
def create_test_line_item():
"""Factory for LineItem with defaults."""
def _create(
product_id: str = "prod_1",
title: str = "Test Product",
quantity: int = 1,
price: float = 99.99,
) -> LineItem:
return LineItem(
product_id=ProductId(product_id),
product_title=ProductTitle(title),
quantity=quantity,
price=Money.from_float(price),
)
return _create
@pytest.fixture
def create_test_order(create_test_line_item):
"""Factory for Order with defaults."""
def _create(
order_id: str = "order_123",
customer_name: str = "Test User",
items: Optional[list[LineItem]] = None,
) -> Order:
if items is None:
items = [create_test_line_item()]
total = sum(
float(item.price.amount) * item.quantity for item in items
)
return Order(
order_id=OrderId(order_id),
created_at=datetime.now(),
customer_name=customer_name,
line_items=items,
total_price=Money.from_float(total),
)
return _create
```
### Step 8: Create Domain-Specific Conftest Files
```python
# tests/unit/extraction/conftest.py - Extraction context fixtures
from __future__ import annotations
from unittest.mock import AsyncMock, create_autospec
import pytest
from app.extraction.application.ports import ShopifyPort, PublisherPort
@pytest.fixture
def mock_shopify_gateway() -> AsyncMock:
"""Mock Shopify gateway for extraction tests."""
mock = create_autospec(ShopifyPort, instance=True)
async def fake_orders():
yield create_test_order(order_id="1")
yield create_test_order(order_id="2")
mock.fetch_orders.return_value = fake_orders()
return mock
@pytest.fixture
def mock_event_publisher() -> AsyncMock:
"""Mock Kafka publisher for extraction tests."""
mock = create_autospec(PublisherPort, instance=True)
mock.publish_order.return_value = None
mock.close.return_value = None
return mock
# tests/unit/reporting/conftest.py - Reporting context fixtures
from __future__ import annotations
from unittest.mock import AsyncMock, create_autospec
import pytest
from app.reporting.application.ports import QueryPort
from app.reporting.domain.entities import ProductRanking
from app.reporting.domain.value_objects import Rank
@pytest.fixture
def mock_query_gateway() -> AsyncMock:
"""Mock ClickHouse query gateway for reporting tests."""
mock = create_autospec(QueryPort, instance=True)
mock.query_top_products.return_value = [
ProductRanking(title="Laptop", rank=Rank(1), cnt_bought=100),
ProductRanking(title="Mouse", rRelated in Data & Analytics
clawarr-suite
IncludedComprehensive management for self-hosted media stacks (Sonarr, Radarr, Lidarr, Readarr, Prowlarr, Bazarr, Overseerr, Plex, Tautulli, SABnzbd, Recyclarr, Unpackerr, Notifiarr, Maintainerr, Kometa, FlareSolverr). Deep library exploration, analytics, dashboard generation, content management, request handling, subtitle management, indexer control, download monitoring, quality profile sync, library cleanup automation, notification routing, collection/overlay management, and media tracker integration (Trakt, Letterboxd, Simkl).
querying-soql
IncludedSOQL query generation, optimization, and analysis with 100-point scoring. Use this skill when the user needs SOQL/SOSL authoring or optimization: natural-language-to-query generation, relationship queries, aggregates, query-plan analysis, and performance or safety improvements for Salesforce queries. TRIGGER when: user writes, optimizes, or debugs SOQL/SOSL queries, touches .soql files, or asks about relationship queries, aggregates, or query performance. DO NOT TRIGGER when: bulk data operations (use handling-sf-data), Apex DML logic (use generating-apex), or report/dashboard queries.
app-store-optimization
IncludedApp Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklists, and tracking ranking changes.
habit-flow
IncludedAI-powered atomic habit tracker with natural language logging, streak tracking, smart reminders, and coaching. Use for creating habits, logging completions naturally ("I meditated today"), viewing progress, and getting personalized coaching.
app-store-optimization
IncludedApp Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklists, and tracking ranking changes.
visualizing-data
IncludedBuilds dashboards, reports, and data-driven interfaces requiring charts, graphs, or visual analytics. Provides systematic framework for selecting appropriate visualizations based on data characteristics and analytical purpose. Includes 24+ visualization types organized by purpose (trends, comparisons, distributions, relationships, flows, hierarchies, geospatial), accessibility patterns (WCAG 2.1 AA compliance), colorblind-safe palettes, and performance optimization strategies. Use when creating visualizations, choosing chart types, displaying data graphically, or designing data interfaces.