Imported from se2p/pynguin (
src/pynguin/testcase/AGENTS.md). Install upstream withnpx skills add se2p/pynguin --skill testcase. Copyright stays with the author.
testcase/
Purpose: Internal representation of generated tests - the core model for test cases, statements, and execution.
Last Updated: 2026-01-30
Overview
This directory contains the complete internal model for representing test cases in Pynguin. It defines the abstract syntax tree (AST) for test cases composed of statements that manipulate variables, and provides execution and export capabilities to convert these internal representations into executable pytest code.
Key Components
Core Models
Statement Types (statement.py)
The fundamental building blocks of test cases. All statements inherit from the abstract Statement base class.
Primitive Statements:
IntPrimitiveStatement,UIntPrimitiveStatement- Integer valuesFloatPrimitiveStatement- Floating-point valuesComplexPrimitiveStatement- Complex numbersStringPrimitiveStatement- String values with multiple implementations:RandomStringPrimitiveStatement- Random stringsFakerStringPrimitiveStatement- Faker-generated stringsFandangoStringPrimitiveStatement- Grammar-based stringsFandangoFakerStringPrimitiveStatement- Combined grammar+faker
BytesPrimitiveStatement- Byte sequencesBooleanPrimitiveStatement- Boolean valuesEnumPrimitiveStatement- Enum valuesClassPrimitiveStatement- Class referencesNoneStatement- None value
Collection Statements:
ListStatement- List collectionsSetStatement- Set collectionsTupleStatement- Tuple collectionsDictStatement- Dictionary collectionsNdArrayStatement- NumPy array collections
Call Statements:
ConstructorStatement- Object instantiationMethodStatement- Method calls on objectsFunctionStatement- Function callsFieldStatement- Field access/assignmentAssignmentStatement- Variable assignment
Base Classes:
Statement- Abstract base for all statementsVariableCreatingStatement- Statements that create variables (have return values)ParametrizedStatement- Statements with parameters (constructors, methods, functions)CollectionStatement- Base for collection typesPrimitiveStatement[T]- Generic base for primitive types
Test Cases (testcase.py, defaulttestcase.py)
TestCase (Abstract Base):
- Interface for test case implementations
- Manages ordered list of statements
- Provides dependency tracking between variables
- Supports cloning, mutation, and structural comparison
Key Operations:
add_statement()- Add statement at positionremove()- Remove statement by positionremove_with_forward_dependencies()- Remove statement and dependentsget_objects()- Find variables of specific typeget_dependencies()- Get backward dependenciesget_forward_dependencies()- Get forward dependenciesclone()- Deep copy with optional limit
Variable References (variablereference.py)
Reference Hierarchy:
Reference- Abstract base for anything referenceableVariableReference- Reference to variables in test caseCallBasedVariableReference- Variable with dynamically updated typeFieldReference- Reference to instance fieldsStaticFieldReference- Reference to static class fieldsStaticModuleFieldReference- Reference to module-level fields
Key Concepts:
- Variables identified by object identity (no eq/hash)
- Distance metric for mutation selection
- Structural equality for test case comparison
- Type information tracked per reference
Visitors
Statement Visitor (statement.py)
Abstract visitor pattern for processing statements:
- Visit methods for each statement type
- Used by export, mutation, and analysis
Test Case Visitor (testcasevisitor.py)
Visitor pattern for test case implementations:
visit_default_test_case()- Process test cases
Execution Model (execution.py)
ExecutionContext:
- Maintains execution state (local/global namespaces)
- Variable name management
- Module alias management
- Converts statements to executable AST nodes
Execution Observers:
RemoteExecutionObserver- Base for execution observation- Thread-local state for concurrent execution
- Hooks for before/after test execution
Key Features:
- Converts internal representation to AST
- Manages variable/module namespaces
- Supports remote execution with observers
- Handles assertions alongside statements
Export System (export.py, statement_to_ast.py, testcase_to_ast.py)
Export Pipeline:
PyTestChromosomeToAstVisitor- Visit chromosomes containing test casesTestCaseToAstVisitor- Convert test case to ASTStatementToAstVisitor- Convert individual statements to AST nodes- Generate pytest-compatible Python code
Key Features:
- Module import management with aliases
- Canonical module name resolution
- Pytest function generation
- Support for failing tests (exception assertions)
Local Search & Optimization
Local Search Components:
localsearch.py- Test-case/suite-level orchestration (backwards statement iteration, probability gating, double-branch-coverage duplication)localsearchstatement.py- Per-statement strategies (AVM for int/float, string/bytes char search, bool flip, enum sweep, literal collections, call statements); dispatch byStatement.bound_type/accessible; value access vialiteralgen.parse_literal/literal_to_cstlocalsearchtimer.py- Timing controllocalsearchobjective.py- Objective functions (suite-fitness oracle)llmlocalsearch.py- LLM-assisted local search (currently an inert, default-off hook; re-enable together with the LLM subsystem)
Test Factory
testfactory.py:
- Factory for creating statements
- Handles type-aware statement generation
- Manages test cluster integration
Architecture Patterns
Statement Lifecycle
- Creation: Factory creates typed statement
- Reference: Statement gets
VariableReference(if variable-creating) - Addition: Statement added to test case
- Execution: Context converts to AST and executes
- Export: Statement converted to pytest code
Variable Dependencies
var_0 = Constructor() # No dependencies
var_1 = var_0.method() # Depends on var_0
var_2 = function(var_1) # Depends on var_1 (transitively on var_0)
- Forward dependencies: var_0 → {var_1} → {var_2}
- Backward dependencies: var_2 → {var_1} → {var_0}
Mutation Operations
Statements support mutation through:
mutate()- Mutate statement contentreplace()- Replace variable references- Delta debugging for minimization
Structural Equality
Test cases use structural equality (not object identity):
structural_eq()- Compare statement structurestructural_hash()- Hash statement structure- Memo maps variables between test cases
Key Abstractions
Statement → AST Conversion
Each statement type implements:
accept(visitor)- Visitor pattern entry point- Visitor creates corresponding
ast.stmtnode - Handles variable naming, module aliasing
Execution Context
Manages runtime state:
- Local namespace: Variables created during execution
- Global namespace: Imported modules
- Variable names: Variable reference → name mapping
- Module aliases: Module → alias mapping
Reference System
Variables are references, not values:
VariableReference= handle to variable in test case- References have types (from type inference)
- Types can be updated dynamically (
CallBasedVariableReference) - References support attribute access (
FieldReference)
Dependencies
Internal:
../assertion/- Assertion generation and checking../analyses/- Type system, test cluster../instrumentation/- Code instrumentation for execution../ga/- Genetic algorithm chromosomes../utils/- Naming, randomness, type utilities
External:
ast- Python AST manipulationpytest- Test execution frameworkfaker- String generation (optional)numpy- Array support (optional)multiprocess- Parallel execution
Common Operations
Creating a Test Case
test_case = DefaultTestCase(test_cluster)
stmt = IntPrimitiveStatement(test_case, 42)
var_ref = test_case.add_statement(stmt)
Cloning with Modifications
cloned = test_case.clone(limit=5) # Clone first 5 statements
cloned.chop(3) # Remove statements after position 3
Finding Variables
# Find all variables of type 'int' before position 10
int_vars = test_case.get_objects(IntType(), position=10)
Exporting to Code
visitor = PyTestChromosomeToAstVisitor()
chromosome.accept(visitor)
# visitor.module_aliases contains imports
# visitor.conversion_results contains AST
Testing
This module is tested extensively through:
- Unit tests for statement types
- Integration tests for execution
- Export tests for AST generation
- Mutation tests for genetic operations
Related Documentation
- Statement creation: See
testfactory.py - Execution: See
execution.py,../instrumentation/ - Export: See
export.py,statement_to_ast.py - Assertions: See
../assertion/AGENTS.md - Type system: See
../analyses/typesystem.py