Version: 0.2.0 Status: Fully Functional
pytest-forger is a Python tool designed to forge PyTest-ready tests from existing Python source code.
The goal of the project is to reduce the friction and boilerplate involved in writing tests by automatically generating test scaffolding and mocks based on the structure of your code, while keeping the developer fully in control of the final behavior.
Save up to 60% of test writing time by automating the mechanical parts while you focus on the actual test logic.
pip install pytest-forgerFor development:
pip install -e .# Generate tests for a Python file
ptf forge your_module.py
# Generate tests with verbose output
ptf forge your_module.py --verbose
# Generate tests for a specific function
ptf forge your_module.py --function my_function
# Specify output directory
ptf forge your_module.py --output tests/unit
# Overwrite existing test files
ptf forge your_module.py --overwriteGiven a source file services.py:
from datetime import datetime
from typing import Optional, List
def add_numbers(x: int, y: int) -> int:
"""Add two numbers together."""
return x + y
class UserService:
def __init__(self, repository=None):
self.repository = repository
def get_user(self, user_id: int) -> Optional[dict]:
"""Get a user by ID."""
if self.repository:
return self.repository.find(user_id)
return None
def process_items(self, items: List[str]) -> int:
"""Process a list of items and return count."""
return len(items)Running ptf forge services.py generates tests/test_services.py:
import pytest
from services import *
from unittest.mock import MagicMock, patch
# Tests generated by pytest-forger
def test_add_numbers():
"""Test for add_numbers: Add two numbers together."""
# Arrange
x = 0
y = 0
# Act
# result = services.add_numbers(x, y)
# Assert
assert True # TODO: Replace with actual assertion
def test_UserService_get_user():
"""Test for get_user: Get a user by ID."""
# Arrange
instance = services.UserService()
user_id = 0
# Act
# result = instance.get_user(user_id)
# Assert
assert True # TODO: Replace with actual assertion
def test_UserService_process_items():
"""Test for process_items: Process a list of items and return count."""
# Arrange
instance = services.UserService()
items = List[str]()
# Act
# result = instance.process_items(items)
# Assert
assert True # TODO: Replace with actual assertionDisplay version information about pytest-forger.
$ ptf version
pytest-forger v0.2.0
https://github.com/daryll/pytest-forger
MIT License (c) 2025 Daryll Lorenzo AlfonsoForge PyTest tests from an existing Python source file.
| Option | Short | Description |
|---|---|---|
--function |
-f |
Generate tests only for a specific function |
--output |
-o |
Directory where generated tests will be saved (default: tests/) |
--overwrite |
-w |
Overwrite existing test files if they already exist |
--verbose |
-v |
Show detailed information about the test generation process |
| Feature | Description |
|---|---|
| Static code analysis | Full AST-based parsing of Python source code |
| Function extraction | Detects global functions and class methods |
| Async function support | Recognizes async def functions with pytest-asyncio hints |
| Type hint awareness | Generates type-appropriate placeholders (str, int, List, etc.) |
| External dependency detection | Identifies third-party imports (non-stdlib) |
| Mock scaffolding | Generates mock setup comments for external dependencies |
| Flexible CLI | Filter by function, customize output, verbose mode |
| Comprehensive test suite | 28+ tests covering all core functionality |
| Private method exclusion | Automatically excludes __ and _ methods |
| Docstring extraction | Includes function docstrings in generated tests |
- Call graph analysis for function dependencies
- Automatic mock patching with
@patchdecorators - Fixture generation for common patterns (database, HTTP, etc.)
- Configuration via
pyproject.toml - Support for parametrized test generation
- Integration with popular frameworks (FastAPI, Django, Flask)
pytest-forger is built around a few core principles:
-
Automation without magic Generated tests should be explicit, readable, and predictable.
-
Structure over semantics The tool understands code structure, not business intent.
-
Mocks at the boundaries External dependencies are mocked; internal logic remains real.
-
Developer ownership Generated tests are meant to be edited, extended, and owned by the developer.
pytest-forger is especially useful for:
- Service layers calling repositories or other services
- Legacy codebases with little or no test coverage
- Quickly bootstrapping tests for refactoring
- Teams that want consistency in test structure
- Developers who want to avoid repetitive PyTest boilerplate
To set clear expectations, pytest-forger is not:
- โ A replacement for test design
- โ A business-logic inference engine
- โ A fully autonomous test generator
- โ A PyTest plugin (at least initially)
pytest-forger generates starting points, not perfect tests.
# Run all tests
pytest tests/ -v
# Run with coverage
pytest tests/ --cov=pytest_forgerpytest-forger/
โโโ src/
โ โโโ pytest_forger/
โ โโโ __init__.py
โ โโโ __version__.py
โ โโโ cli.py # CLI entry point (Typer)
โ โโโ core.py # Code analysis & generation
โโโ tests/
โ โโโ fixtures/ # Sample files for testing
โ โโโ test_cli.py # CLI tests
โ โโโ test_core.py # Core functionality tests
โโโ example_app/ # Practical example application
โ โโโ user_service.py # Sample service with dependencies
โ โโโ tests/ # Generated and completed tests
โโโ pyproject.toml
โโโ README.md
- Full AST-based code analysis - Complete implementation of Python source parsing
- Class method extraction - Methods are extracted with proper class context
- Async function detection - Recognizes
async defand adds pytest-asyncio hints - Type hint extraction - Extracts and uses type hints for smarter placeholders
- External dependency detection - Identifies non-stdlib imports automatically
- Mock generation scaffolding - Generates mock setup for external dependencies
- Comprehensive test suite - 28 tests covering CLI and core functionality
- Verbose mode enhancements - Shows detected external dependencies count
- Docstring extraction - Includes function docstrings in generated test descriptions
- Example application - Practical example showing real-world usage
- Class methods now properly extracted with class name context
- Private/protected methods (starting with
_) are correctly excluded - Removed placeholder comments from generated imports
- Args now return structured data with type hints instead of plain strings
generate_test_content()now acceptsexternal_depsparameter for mock generation- CLI passes external dependencies from analyzer to content generator
- Test output includes mock setup section for external dependencies
- Initial CLI implementation using Typer framework
ptf versioncommand to display project version and informationptf forge <source_file.py>command interface for test generation- Complete argument parsing system with options:
--function/-f- Target specific function for test generation--output/-o- Custom output directory for generated tests--overwrite/-w- Overwrite existing test files--verbose/-v- Enable detailed output for debugging
- Project structure with
src/layout - PyPI-ready packaging configuration in
pyproject.toml - Dependencies:
pytest>=7.4.0,typer>=0.9.0
ptf forgeprovided the interface without actual code analysis- This release established the foundation for test generation
pytest-forger exists to answer one simple question:
"How much of testing can we automate without lying to ourselves?"
The answer is: a lot of the boring parts.
- No manual imports - pytest, unittest.mock, your module
- No structure setup - Arrange-Act-Assert pattern pre-built
- No fixture boilerplate - Class instantiation ready
- No argument guessing - Type hints provide placeholders
- No dependency hunting - External imports detected automatically
- Test logic - Actual assertions and behavior
- Edge cases - Boundary conditions and error handling
- Mock configuration - Return values and side effects
- Business rules - Domain-specific validation
MIT License
pytest-forger is an early-stage project under active design. Breaking changes are expected in early versions.
Forge tests, not excuses.
