test-implement-factory-fixtures
Create factory fixture patterns for customizable test setup with variations. Use when building reusable test fixtures with multiple configurations, creating parameterizable mocks, or implementing test data builders. Works with pytest fixtures, mock objects, and test utilities. Enables DRY test setup while maintaining flexibility for edge cases.
What this skill does
# Implement Factory Fixtures
## Purpose
Factory fixtures are pytest fixtures that return callable functions, enabling dynamic test setup with customizable parameters. This pattern eliminates test duplication while maintaining flexibility for edge cases and variations.
## Quick Start
```python
# Create a factory fixture
@pytest.fixture
def mock_service_factory():
def create_service(dimensions=384, success=True):
service = AsyncMock()
service.generate = AsyncMock(return_value=[0.1] * dimensions)
return service
return create_service
# Use in tests
def test_with_custom_dimensions(mock_service_factory):
service = mock_service_factory(dimensions=1536)
result = service.generate()
assert len(result) == 1536
```
## Table of Contents
### Core Sections
- [When to Use Factory Fixtures](#step-1-identify-the-need-for-factory-fixtures)
- Multiple test variations needed
- Parameterization insufficient
- Edge cases require customization
- Real objects with mock dependencies
- [Factory Design Patterns](#step-2-design-the-factory-function)
- Standard factory fixture structure
- Outer fixture, inner function, default values
- Proper documentation and type hints
- [Common Factory Patterns](#step-3-implement-common-factory-patterns)
- [Pattern A: Mock Service Factory](#pattern-a-mock-service-factory) - Services with success/failure modes, varying return types
- [Pattern B: Settings Factory](#pattern-b-settings-factory) - Configuration objects with many attributes
- [Pattern C: Real Instance Factory](#pattern-c-real-instance-factory) - Real objects with mock dependencies
- [Pattern D: Result/Data Factory](#pattern-d-resultdata-factory) - ServiceResult mocks, query results, response objects
- [Organization and Usage](#step-4-organize-factory-fixtures)
- File organization patterns
- Naming conventions
- Using factories in tests
### Examples
- [Example 1: Embedding Service Factory](#example-1-embedding-service-factory-from-project)
- Custom dimensions (384, 1536)
- Success/failure modes
- Error message handling
- [Example 2: Settings Factory with Kwargs](#example-2-settings-factory-with-kwargs-from-project)
- Hierarchical settings structure
- Flexible kwargs overrides
- Default value management
- [Example 3: Real Instance Factory](#example-3-real-instance-factory-with-mock-dependencies)
- Real business logic with mocked dependencies
- Combining multiple factories
- Custom configuration testing
### Decision Guidance
- [Factory vs Parametrize](#factory-vs-parametrize-when-to-choose)
- When to use factory fixtures
- When to use pytest.mark.parametrize
- Comparison examples
### Common Pitfalls
- [Pitfall 1: Over-Parameterization](#pitfall-1-over-parameterization) - Too many parameters, use kwargs instead
- [Pitfall 2: Missing Defaults](#pitfall-2-missing-defaults) - Force every test to specify everything
- [Pitfall 3: Stateful Factories](#pitfall-3-stateful-factories) - State leaks between tests
- [Pitfall 4: Not Using Type Hints](#pitfall-4-not-using-type-hints) - Unclear return types
### Supporting Resources
- [Requirements](#requirements)
- [See Also](#see-also) - Project examples, related skills, pytest documentation
### Python Examples
- [Convert Fixture to Factory](./scripts/convert_fixture_to_factory.py) - Convert existing pytest fixtures to factory pattern
- [Generate Factory Fixture](./scripts/generate_factory_fixture.py) - Auto-generate factory fixtures from class definitions
- [Validate Fixtures](./scripts/validate_fixtures.py) - Analyze fixtures and suggest factory pattern conversions
## Instructions
### Step 1: Identify the Need for Factory Fixtures
Factory fixtures are ideal when:
- **Multiple test variations needed**: Same mock with different configurations
- **Parameterization insufficient**: pytest.mark.parametrize doesn't capture all variations
- **Edge cases require customization**: Success/failure modes, different data shapes
- **Real objects with mock dependencies**: Creating real instances with injected mocks
**Example Scenarios:**
- Mock service returning different dimension embeddings (384, 1536, etc.)
- Settings objects with various configuration combinations
- Real service instances with mocked dependencies
- Query results with different data structures
### Step 2: Design the Factory Function
Factory fixtures have three components:
1. **Outer fixture**: Declares dependencies and returns factory function
2. **Inner factory function**: Accepts parameters and creates instances
3. **Default values**: Sensible defaults for common cases
**Standard Pattern:**
```python
@pytest.fixture
def mock_thing_factory():
"""Create a factory for custom mock things.
Returns:
callable: Function that creates things with custom parameters
Example:
def test_something(mock_thing_factory):
thing = mock_thing_factory(param1=value1, param2=value2)
# Use thing in test
"""
def create_thing(param1=default1, param2=default2):
"""Create custom mock thing.
Args:
param1: Description (default: default1)
param2: Description (default: default2)
Returns:
Type: Custom thing instance
"""
# Implementation
return thing
return create_thing
```
### Step 3: Implement Common Factory Patterns
#### Pattern A: Mock Service Factory
For mocks with varying behavior:
```python
@pytest.fixture
def mock_embedding_service_factory():
def create_service(dimensions=384, success=True, error_message=None):
service = AsyncMock()
if success:
service.generate_embeddings = AsyncMock(
return_value=MagicMock(
success=True,
data=[[0.1] * dimensions],
)
)
else:
service.generate_embeddings = AsyncMock(
return_value=MagicMock(
success=False,
error=error_message or "Embedding service error"
)
)
return service
return create_service
```
**Use for**: Services with success/failure modes, varying return types, different dimensions.
#### Pattern B: Settings Factory
For configuration objects with many attributes:
```python
@pytest.fixture
def mock_settings_factory():
def create_settings(**kwargs):
settings = MagicMock()
# Set default structure
settings.project = MagicMock()
settings.neo4j = MagicMock()
settings.chunking = MagicMock()
# Apply defaults with kwargs overrides
settings.project.project_name = kwargs.get("project_name", "test_project")
settings.chunking.chunk_size = kwargs.get("chunk_size", 50)
settings.neo4j.database_name = kwargs.get("database_name", "test_db")
return settings
return create_settings
```
**Use for**: Complex configuration objects, hierarchical settings, many attributes.
#### Pattern C: Real Instance Factory
For creating real objects with mock dependencies:
```python
@pytest.fixture
def mock_indexing_module_factory(
mock_neo4j_driver,
mock_embedding_service_factory,
mock_settings_factory
):
def create_module(**kwargs):
from project_watch_mcp.infrastructure.neo4j.graphrag.indexing import IndexingModule
settings = mock_settings_factory(**kwargs)
embedder = mock_embedding_service_factory(
dimensions=kwargs.get("embedding_dimensions", 384)
)
return IndexingModule(
settings=settings,
db=mock_neo4j_driver,
embedder=embedder,
project_name=kwargs.get("project_name", "test_project"),
database=kwargs.get("database", "test_db"),
)
return create_module
```
**Use for**: Testing real business logic with controlled dependencies.
#### Pattern D: Result/Data Factory
For Related in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.