| name | python-pytest-creator-skill |
| description | Generate comprehensive pytest test files for Python using the test-generator-framework Use when this capability is needed. |
| metadata | {"author":"darellchua2"} |
What I do
I implement a complete Python pytest test generation workflow by extending the test-generator-framework:
- Analyze Python Codebase: Scan Python application to identify functions, classes, and modules
- Detect Python Testing Setup: Identify pytest version and Poetry availability
- Generate Python-Specific Scenarios: Create comprehensive test scenarios covering:
- Happy paths, edge cases, and error handling
- Python-specific patterns (decorators, context managers, async functions)
- Delegate to Framework: Use
test-generator-framework for core test generation workflow
- Ensure Executability: Verify tests run with
poetry run pytest or pytest
When to use me
Use this workflow when:
- You need to create comprehensive pytest test files for a Python application
- You want to ensure all edge cases and error conditions are covered
- You need tests that integrate with Poetry environments
- You prefer a systematic approach to test generation with user confirmation
- You want to ensure tests run correctly with your project's pytest version
Framework: This skill extends test-generator-framework for core test generation workflow, adding Python-specific functionality.
Prerequisites
- Python project with Poetry (
pyproject.toml) or pip (requirements.txt)
- Pytest installed and configured in project
- Python source code to test
- Appropriate file permissions to create test files
Note: Poetry is optional. If Poetry is installed and pyproject.toml exists, tests will use poetry run pytest. Otherwise, tests will use pytest directly.
Steps
Step 1: Analyze Python Codebase
- Use glob patterns to find Python files:
**/*.py
- Exclude test files:
**/test_*.py, **/*_test.py, **/tests/**/*.py
- Read each Python file to identify:
- Functions:
def function_name(parameters):
- Classes:
class ClassName:
- Methods:
def method_name(self, parameters):
- Async functions:
async def async_function():
- Decorators:
@decorator_name
- Context managers:
with context_manager():
- Identify import statements to understand dependencies
Step 2: Detect Python Testing Setup
- Check for
pyproject.toml or requirements.txt
- Determine pytest version and plugins
- Check for Poetry installation:
poetry --version
Step 3: Generate Python-Specific Test Scenarios
Function Scenarios (Python-specific)
- Happy Path: Normal inputs with expected outputs
- Edge Cases: Empty strings, empty lists,
None, 0, -1
- Error Cases: Invalid types, out of range values, missing parameters
- Python Features: Decorators, type hints, default arguments, *args/**kwargs
Class Scenarios
- Initialization:
__init__ with valid/invalid parameters
- Method Behavior: Public/private method testing
- Special Methods:
__str__, __repr__, __eq__, __hash__
- Class Methods:
@classmethod, @staticmethod
- Property: Properties defined with
@property
- Context Managers:
__enter__ and __exit__ methods
Async Function Scenarios
- Awaitable Results: Normal async execution
- Concurrency: Multiple async calls with asyncio.gather()
- Error Handling: Async exceptions with pytest.raises()
- Timeout: Tests that should timeout
Step 4: Delegate to Test Generator Framework
Note: Core test generation workflow is provided by test-generator-framework. This skill focuses only on Python-specific aspects.
Refer to test-generator-framework for:
- Generic test file creation structure
- Framework detection and command determination
- User confirmation workflow
- Executability verification
Python-specific test file templates below extend the framework structure.
Step 5: Create Test Files (Python-specific)
"""
Test suite for <module_name>.py
Generated by python-pytest-creator skill
"""
import pytest
from <module_path> import <function_name>, <ClassName>
@pytest.fixture
def sample_instance():
"""Create a sample instance for testing"""
return ClassName(param1, param2)
def test_function_name_happy_path(sample_instance):
"""Test that function_name works with valid inputs"""
result = function_name(valid_input)
assert result == expected_output
def test_function_name_edge_case_empty():
"""Test that function_name handles empty input"""
result = function_name("")
assert result is None
def test_function_name_error_invalid_type():
"""Test that function_name raises ValueError for invalid type"""
with pytest.raises(ValueError):
function_name(invalid_input)
@pytest.mark.parametrize("input,expected", [
(1, "one"),
(2, "two"),
])
def test_function_name_parametrized(input, expected):
"""Test function_name with multiple inputs"""
result = function_name(input)
assert result == expected
class TestClassName:
"""Test suite for ClassName"""
():
instance = ClassName(param1, param2)
instance.attribute == expected_value
():
result = sample_instance.method_name(param)
result == expected_result
():
result = async_function(valid_input)
result[] ==
Step 6: Verify Executability
Refer to test-generator-framework for core executability verification.
Step 7: Display Summary
✅ Python test files created successfully!
**Test Files Created:**
- tests/test_<module_name>.py (<number> tests)
**Total Tests Generated:** <number>
**Test Framework:** Pytest
**Python-Specific Categories:**
- Decorator tests: <number>
- Context manager tests: <number>
- Special method tests: <number>
- Async function tests: <number>
To run tests:
poetry run pytest tests/test_<module_name>.py -v
poetry run pytest --cov=<module_name> tests/
pytest tests/test_<module_name>.py -v
pytest --cov=<module_name> tests/
Python-Specific Scenario Generation
Python-specific patterns to focus on:
Decorator Testing
- Decorator Execution: Decorator modifies function behavior correctly
- Decorator Chaining: Multiple decorators apply correctly
- Decorator Arguments: Decorator with parameters works
- Class Decorators: Decorator classes properly
Context Manager Testing
__enter__: Returns context manager correctly
__exit__: Cleans up resources properly
- Exception Handling: Exceptions in context are handled
- Nested Context: Multiple context managers work together
Special Method Testing
__str__: String representation is correct
__repr__: Developer representation is correct
__eq__: Equality comparison works
__hash__: Hash allows use in sets/dicts
__len__: Length function returns correct value
__getitem__: Item access works
__setitem__: Item assignment works
Property Testing
- Getter: Property returns correct value
- Setter: Property sets value correctly
- Deleter: Property deletion works
- Cached Properties: Cached behavior is correct
Best Practices
Refer to test-generator-framework for general best practices.
Python-specific best practices:
- Pytest Features: Use fixtures, parametrization, marks
- Async Testing: Use pytest-asyncio for async functions
- Type Hints: Include type hints for better test coverage
- Mocking: Use pytest-mock or unittest.mock appropriately
- Integration Tests: Always include at least one integration test with real database sessions — mock-only tests mask session boundary bugs
Common Issues
Refer to test-generator-framework for general issues.
Python-specific issues:
Poetry Not Installed
Issue: poetry run pytest command not found
Solution: Use pytest directly instead:
pytest tests/
pytest-asyncio Not Installed
Issue: Async tests fail or don't run
Solution: Install pytest-asyncio:
poetry add --group dev pytest-asyncio
pip install pytest-asyncio
Module Not Found
Issue: Import errors for modules to test
Solution: Add source to PYTHONPATH:
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
MagicMock Truthy Headers
Issue: MagicMock for response.headers creates truthy auto-created mocks, causing false positives in header-checking code.
mock_response = MagicMock()
mock_response.headers.get.return_value = "Bearer test-token"
assert mock_response.headers.get("Authorization") == "Bearer test-token"
mock_response = MagicMock()
mock_response.headers = {"Authorization": "Bearer test-token"}
assert mock_response.headers.get("Authorization") == "Bearer test-token"
assert mock_response.headers.get("X-Missing") is None
Detached ORM Across Sessions (Mocking Pitfall)
Issue: Mock-only tests mask session boundary bugs. When an ORM object is fetched in one session and mutated in another, mocks won't catch the detached state.
mock_session = MagicMock()
mock_session.get.return_value = User(id="u1", name="old")
repo = UserRepository(mock_session)
repo.update_name("u1", "new")
mock_session.commit.assert_called_once()
@pytest.mark.asyncio
async def test_update_user_real_session(test_db_session):
user = User(id="u1", name="old")
test_db_session.add(user)
await test_db_session.commit()
fetched = await test_db_session.get(User, "u1")
fetched.name = "new"
await test_db_session.commit()
result = await test_db_session.get(User, "u1")
assert result.name == "new"
Troubleshooting Checklist
Refer to test-generator-framework for general checklist.
Python-specific additions:
Before generating tests:
Related Commands
poetry run pytest -v
poetry run pytest --cov=<module> tests/
poetry install --group dev pytest-asyncio
pytest -v
pytest tests/test_module.py -v
pytest --cov=<module> tests/
pytest -k "test_name"
python -m pytest
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
Source: darellchua2/opencode-config-template — distributed by TomeVault.