generate-python-unit-tests
npx skills add https://github.com/olino3/forge --skill generate-python-unit-tests
Agent 安装分布
Skill 文档
generate-python-unit-tests
Title
Python Unit Test Generator – Intelligent unit test generation with Socratic planning and project-specific memory.
Version
v1.0.0 – Initial release
File Structure
Skill Files
forge-plugin/skills/generate-python-unit-tests/
âââ SKILL.md # This file
âââ examples.md # Usage examples
âââ scripts/
â âââ test_analyzer.py # Helper for analyzing existing tests
âââ templates/
âââ test_file_template.txt # Standard test file structure
âââ test_case_template.txt # Individual test case template
Interface References
- ContextProvider â
getDomainIndex("python"),getConditionalContext("python", topic) - MemoryStore â
getSkillMemory("generate-python-unit-tests", project),update()
Context (via ContextProvider)
contextProvider.getDomainIndex("python")â Python context navigationcontextProvider.getConditionalContext("python", "unit_testing_standards")â Unit testing best practicescontextProvider.getConditionalContext("python", "testing_frameworks")â pytest, unittest, etc.contextProvider.getConditionalContext("python", "mocking_patterns")â Mock/patch patternscontextProvider.getConditionalContext("python", "test_antipatterns")â What to avoid
Memory (via MemoryStore)
memoryStore.getSkillMemory("generate-python-unit-tests", project)returns per-project files:testing_patterns.mdâ Project’s testing conventionsexpected_behaviors.mdâ Known expected behaviorscommon_fixtures.mdâ Reusable test fixturesframework_config.mdâ Testing framework setup
Required Reading
Context & Memory Loading (via Interfaces)
Before starting any test generation, load resources in this order:
-
Project Memory (via MemoryStore):
memoryStore.getSkillMemory("generate-python-unit-tests", project)â loads all per-project files if they exist
-
Domain Index (via ContextProvider):
contextProvider.getDomainIndex("python")â Python context navigation and framework detection
-
Core Testing Context (always load via ContextProvider):
contextProvider.getConditionalContext("python", "unit_testing_standards")â Core testing principlescontextProvider.getConditionalContext("python", "testing_frameworks")â Framework-specific patternscontextProvider.getConditionalContext("python", "mocking_patterns")â Mocking best practicescontextProvider.getConditionalContext("python", "test_antipatterns")â What to avoid
-
Conditional Context (load based on code analysis):
- Load additional context from Python domain via
contextProvider.getConditionalContext()as needed
- Load additional context from Python domain via
Loading Order
CRITICAL: Resources must be loaded in this exact order:
1. Project memory via memoryStore (load project-specific patterns)
2. Domain index via contextProvider (understand available context)
3. Core context via contextProvider (testing standards, frameworks)
4. Conditional context via contextProvider (based on code being tested)
Design Requirements
Core Principles
- Practical Tests: Generate tests that validate real behavior, not implementation details
- Maintainability: Tests should be easy to understand and update
- Non-Brittleness: Tests should not break on refactoring unless behavior changes
- Socratic Planning: Collaborate with user to understand expected behavior
- Project Memory: Learn and apply project-specific testing patterns
- Framework Awareness: Support pytest, unittest, and other frameworks
- Comprehensive Coverage: Include happy paths, edge cases, and error scenarios
Test Quality Criteria
Generated tests must:
- â Test behavior, not implementation
- â Have clear, descriptive names (test_should_X_when_Y)
- â Follow AAA pattern (Arrange, Act, Assert)
- â Be independent and isolated
- â Use appropriate mocking/patching
- â Include meaningful assertions
- â Document complex test scenarios
- â Follow project conventions from memory
What NOT to Do
- â Test private methods directly
- â Create brittle tests tied to implementation
- â Generate tests without understanding expected behavior
- â Ignore existing project testing patterns
- â Over-mock or under-mock
- â Skip error/edge case scenarios
- â Use generic test names
Prompting Guidelines
User Interaction Phases
Phase 1: Initial Analysis
- Identify files to test
- Analyze existing test structure
- Detect testing framework
Phase 2: Socratic Planning (MANDATORY)
- Ask targeted questions about expected behavior
- Clarify edge cases and error scenarios
- Understand business logic and constraints
- Confirm testing approach
Phase 3: Test Generation
- Generate tests based on planning
- Apply project memory patterns
- Follow testing standards
Socratic Questions Framework
Ask questions in these categories:
-
Behavior Understanding:
- “What should happen when [normal input]?”
- “How should the function behave when [edge case]?”
- “What errors should be raised when [invalid input]?”
-
Dependencies & Integration:
- “Should I mock [dependency] or use real instances?”
- “What external services need to be mocked?”
- “Are there database/file system interactions to consider?”
-
Business Logic:
- “What business rules govern [functionality]?”
- “Are there constraints or validations I should test?”
- “What are the success/failure criteria?”
-
Test Approach:
- “Do you prefer parameterized tests or individual test cases?”
- “Should I include integration tests or focus on unit tests?”
- “Are there specific scenarios you’re concerned about?”
Instructions
Mandatory Workflow (8 Steps)
This workflow is MANDATORY and NON-NEGOTIABLE. Every step must be completed in order.
Step 1: Initial Analysis
Purpose: Gather information about what needs to be tested.
Actions:
- Identify the Python file(s) or module(s) to test
- Determine the project name from git repository or directory structure
- Check if tests already exist for the target files
- Identify the testing framework (pytest, unittest, etc.)
- List the functions/classes/methods that need test coverage
Validation:
- Target files identified
- Project name determined
- Testing framework detected
- Functions/classes to test listed
Step 2: Load Index Files
Purpose: Understand what memory and context is available.
Actions:
- Load Python domain index via
contextProvider.getDomainIndex("python") - Identify which context topics will be needed based on code analysis
Validation:
- Domain index loaded
- Python context map understood
- Relevant topics identified
Step 3: Load Project Memory
Purpose: Load project-specific testing patterns and conventions.
Actions:
- Load project memory via
memoryStore.getSkillMemory("generate-python-unit-tests", project) - If memory exists, review all files:
testing_patterns.md– Project’s testing conventionsexpected_behaviors.md– Known expected behaviorscommon_fixtures.md– Reusable test fixturesframework_config.md– Testing framework setup
- If no memory exists, note that this is a new project (memory will be created later)
Validation:
- Project memory checked
- Existing patterns loaded (if available)
- Ready to create new memory (if needed)
Step 4: Load Context
Purpose: Load testing standards and best practices.
Actions:
-
Always load:
contextProvider.getConditionalContext("python", "unit_testing_standards")contextProvider.getConditionalContext("python", "testing_frameworks")contextProvider.getConditionalContext("python", "mocking_patterns")contextProvider.getConditionalContext("python", "test_antipatterns")
-
Conditionally load (based on code analysis):
- If async code: load async patterns via contextProvider
- If Django/Flask/FastAPI: load framework-specific context
- If database code: load data testing patterns
- Use domain index from Step 2 as guide
Validation:
- Core testing context loaded
- Framework-specific context loaded (if needed)
- Ready to apply testing standards
Step 5: Analyze Files to Test
Purpose: Understand the code structure and dependencies.
Actions:
- Read the target Python file(s) completely
- Identify:
- Public functions/methods (primary test targets)
- Function signatures and parameters
- Dependencies (imports, external services)
- Error handling (exceptions raised)
- Complexity and edge cases
- Read existing tests (if any) to understand coverage gaps
- Analyze project structure to determine test file location
Validation:
- Target code thoroughly understood
- Dependencies identified
- Edge cases noted
- Test file location determined
Step 6: Socratic Planning Phase
Purpose: Collaborate with the user to understand expected behavior.
CRITICAL: This step is MANDATORY. You MUST ask the user questions before generating tests.
Actions:
- Present a summary of what you analyzed
- Ask targeted questions using the Socratic Questions Framework:
- Behavior questions: Expected outputs, edge cases, errors
- Dependency questions: What to mock, external services
- Business logic questions: Rules, constraints, validations
- Testing approach questions: Style preferences, test types
- Wait for user responses
- Use AskUserQuestion tool for structured multi-choice questions when appropriate
- Clarify ambiguities and confirm understanding
Example Questions:
I analyzed `user_service.py` and found 3 functions to test:
- create_user(username, email, password)
- authenticate_user(username, password)
- delete_user(user_id)
Before generating tests, I need to understand the expected behavior:
1. **For create_user**:
- What should happen if username already exists?
- Should it validate email format?
- What password requirements should I test?
2. **For authenticate_user**:
- Should I mock the database lookup?
- What happens with invalid credentials?
- Are there rate limiting or security concerns?
3. **For delete_user**:
- What happens if user doesn't exist?
- Should it handle cascade deletions?
- Are there permission checks to test?
4. **General**:
- Do you prefer pytest or unittest?
- Should I use fixtures for common setup?
Validation:
- Summary presented to user
- At least 3-5 meaningful questions asked
- User responses received
- Expected behaviors clarified
- Testing approach confirmed
Step 7: Generate Unit Tests
Purpose: Create comprehensive, maintainable unit tests.
Actions:
- Create test file following project conventions:
- File naming:
test_{module_name}.pyor{module_name}_test.py - Location: Based on project structure (e.g.,
tests/,test/, same directory)
- File naming:
- Apply templates from
./templates/test_file_template.txt - For each function/method:
- Generate happy path tests
- Generate edge case tests
- Generate error scenario tests
- Use AAA pattern (Arrange, Act, Assert)
- Include:
- Descriptive test names (test_should_X_when_Y)
- Appropriate mocks/patches
- Fixtures for common setup
- Docstrings for complex tests
- Apply project memory patterns and user’s clarified behaviors
- Follow framework-specific conventions (pytest vs unittest)
Validation:
- Test file created in correct location
- All functions have test coverage
- Happy paths tested
- Edge cases tested
- Error scenarios tested
- Project conventions followed
- User’s expected behaviors implemented
Step 8: Update Project Memory
Purpose: Store learned patterns for future test generation.
Actions:
- Use
memoryStore.update("generate-python-unit-tests", project, filename, content)for each file - Create or update memory files:
- testing_patterns.md: Document testing conventions observed/established
- Test file location pattern
- Naming conventions
- Testing framework and version
- Common patterns used
- expected_behaviors.md: Document clarified behaviors from Socratic phase
- Function behaviors confirmed with user
- Edge case handling rules
- Error scenarios and expected exceptions
- common_fixtures.md: Document reusable test fixtures created
- Shared setup code
- Common mock objects
- Test data factories
- framework_config.md: Document testing framework configuration
- pytest.ini / setup.cfg settings
- Conftest.py patterns
- Plugin usage
- testing_patterns.md: Document testing conventions observed/established
Validation:
- Project memory directory exists
- testing_patterns.md created/updated
- expected_behaviors.md created/updated
- common_fixtures.md created/updated
- framework_config.md created/updated
Compliance Checklist
Before completing the skill invocation, verify ALL items:
Workflow Compliance
- Step 1: Initial Analysis completed
- Step 2: Index files loaded
- Step 3: Project memory loaded
- Step 4: Context loaded
- Step 5: Files analyzed
- Step 6: Socratic planning completed (questions asked and answered)
- Step 7: Tests generated
- Step 8: Memory updated
Test Quality
- Tests follow AAA pattern
- Test names are descriptive
- Appropriate mocking used
- Edge cases covered
- Error scenarios covered
- Tests are independent
- Project conventions followed
Memory & Context
- Project memory checked and loaded
- New patterns documented in memory
- User-clarified behaviors stored
- Testing context applied
User Collaboration
- Socratic questions asked (minimum 3-5)
- User responses incorporated
- Expected behaviors confirmed
Best Practices
Test Organization
-
File Structure:
- Mirror source code structure in tests
- One test file per source file (generally)
- Group related tests in classes
-
Test Naming:
test_should_{expected_behavior}_when_{condition}- Be specific and descriptive
- Use underscores for readability
-
Test Independence:
- Each test should run independently
- Use fixtures for setup/teardown
- Avoid test interdependencies
Mocking Strategy
-
What to Mock:
- External services (APIs, databases)
- File system operations
- Time/date operations
- Random number generation
- Expensive computations
-
What NOT to Mock:
- Code under test
- Simple data structures
- Language built-ins (unless necessary)
Coverage Strategy
-
Priority Order:
- Happy path (normal operation)
- Common edge cases
- Error scenarios
- Boundary conditions
- Integration points
-
Sufficiency:
- Aim for meaningful coverage, not 100%
- Focus on critical business logic
- Test public interfaces
Additional Notes
Testing Frameworks
pytest (preferred):
- Use fixtures for setup
- Parametrize tests for multiple cases
- Use markers for categorization
- Leverage pytest plugins
unittest:
- Use setUp/tearDown for fixtures
- Subclass unittest.TestCase
- Use self.assert* methods
- Mock with unittest.mock
Integration with Other Skills
- Before testing: Use
skill:python-code-reviewto understand code quality - After testing: Review generated tests with
skill:python-code-review - For changes: Use
skill:get-git-diffto see what changed and needs new tests
Common Patterns
- Fixtures:
@pytest.fixture
def sample_user():
return User(username="test", email="test@example.com")
- Parameterization:
@pytest.mark.parametrize("input,expected", [
(1, 2),
(2, 4),
(3, 6),
])
def test_double(input, expected):
assert double(input) == expected
- Mocking:
@patch('module.external_api_call')
def test_function(mock_api):
mock_api.return_value = {'status': 'success'}
result = function_using_api()
assert result == expected
Memory Evolution
Project memory should grow with each invocation:
- First time: Establish basic patterns
- Subsequent times: Refine and expand patterns
- Always: Store user-clarified behaviors
Context Usage
Context files provide stable guidance:
- Testing standards (what makes a good test)
- Framework patterns (how to use pytest/unittest)
- Antipatterns (what to avoid)
- Mocking strategies (when and how to mock)
Version History
v1.1.0 (2025-07-15)
- Phase 4 Migration: Replaced hardcoded
../../context/and../../memory/paths with ContextProvider and MemoryStore interface calls - Added YAML frontmatter with context/memory declarations
- Added Interface References section
- Updated workflow steps to use contextProvider/memoryStore
v1.0.0 (2025-11-18)
- Initial release
- Mandatory 8-step workflow
- Socratic planning phase
- Project-specific memory system
- Centralized context integration
- Support for pytest and unittest
- Template-based test generation