Reference
pynguin.cli
Pynguin is an automated unit test generation framework for Python.
This module provides the main entry location for the program execution from the command line.
- pynguin.cli.main(argv=None)[source]
Entry point for the CLI of the Pynguin automatic unit test generation framework.
This method behaves like a standard UNIX command-line application, i.e., the return value 0 signals a successful execution. Any other return value signals some errors. This is, e.g., the case if the framework was not able to generate one successfully running test case for the class under test.
pynguin.configuration
Provides a configuration interface for the test generator.
- class pynguin.configuration.Algorithm(value)[source]
Different algorithms supported by Pynguin.
- DYNAMOSA = 'DYNAMOSA'
The dynamic many-objective sorting algorithm (cf. Panichella et al. Automated test case generation as a many-objective optimisation problem with dynamic selection of the targets. TSE vol. 44 issue 2).
- LLM = 'LLM'
This does not execute the usual test and assertion generation stages of Pynguin but queries an LLM and writes the resulting test cases to the output file.
- Type:
Query a large language model for tests. NOTE
- LLMOSA = 'LLMOSA'
The many-objective sorting algorithm with LLM.
- MIO = 'MIO'
The MIO test suite generation algorithm (cf. Andrea Arcuri. Many Independent Objective (MIO) Algorithm for Test Suite Generation. Proc. SBSE 2017).
- MOSA = 'MOSA'
The many-objective sorting algorithm (cf. Panichella et al. Reformulating Branch Coverage as a Many-Objective Optimization Problem. Proc. ICST 2015).
- RANDOM = 'RANDOM'
A feedback-direct random test generation approach similar to the algorithm proposed by Randoop (cf. Pacheco et al. Feedback-directed random test generation. Proc. ICSE 2007).
- RANDOM_TEST_CASE_SEARCH = 'RANDOM_TEST_CASE_SEARCH'
Performs random search on test cases.
- RANDOM_TEST_SUITE_SEARCH = 'RANDOM_TEST_SUITE_SEARCH'
Performs random search on test suites.
- WHOLE_SUITE = 'WHOLE_SUITE'
A whole-suite test generation approach similar to the one proposed by EvoSuite (cf. Fraser and Arcuri. EvoSuite: Automatic Test Suite Generation for Object-Oriented Software. Proc. ESEC/FSE 2011).
This algorithm can be modified to use an archive (cf. Rojas, José Miguel, et al. “A detailed investigation of the effectiveness of whole test suite generation.” Empirical Software Engineering 22.2 (2017): 852-893.), by using the following options: –use-archive True, –seed-from-archive True and –filter-covered-targets-from-test-cluster True.
- class pynguin.configuration.AssertionGenerator(value)[source]
Different approaches for assertion generation supported by Pynguin.
- CHECKED_MINIMIZING = 'CHECKED_MINIMIZING'
All assertions that do not increase the checked coverage are removed.
- LLM = 'LLM'
Use Large Language Model(LLM) for assertion generation.
- MUTATION_ANALYSIS = 'MUTATION_ANALYSIS'
Use the mutation analysis approach for assertion generation.
- NONE = 'NONE'
Do not create any assertions.
- SIMPLE = 'SIMPLE'
Use the simple approach for primitive and none assertion generation.
- class pynguin.configuration.Configuration(project_path, module_name, test_case_output, algorithm=Algorithm.DYNAMOSA, statistics_output=<factory>, stopping=<factory>, large_language_model=<factory>, string_statement=<factory>, seeding=<factory>, type_inference=<factory>, pynguinml=<factory>, test_creation=<factory>, generator_selection=<factory>, search_algorithm=<factory>, mio=<factory>, random=<factory>, to_cover=<factory>, ignore_modules=<factory>, ignore_methods=<factory>, subprocess=False, subprocess_if_recommended=True, local_search=<factory>, use_master_worker=True, filesystem_isolation=False)[source]
General configuration for the test generator.
-
filesystem_isolation:
bool= False Whether to use filesystem isolation during test execution. Filesystem isolation provides some safety by tracking and controlling file operations, e.g. preventing file deletion of non-created files, but adds performance overhead.
-
large_language_model:
LLMConfiguration Large Language Model(LLM) configuration.
-
local_search:
LocalSearchConfiguration Local search configuration.
-
mio:
MIOConfiguration Configuration used for the MIO algorithm.
-
pynguinml:
PynguinMLConfiguration PynguinML configuration.
-
random:
RandomConfiguration Configuration used for the RANDOM algorithm.
-
search_algorithm:
SearchAlgorithmConfiguration Search algorithm configuration.
-
seeding:
SeedingConfiguration Seeding configuration.
-
statistics_output:
StatisticsOutputConfiguration Statistic Output configuration.
-
stopping:
StoppingConfiguration Stopping configuration.
-
string_statement:
StringStatementConfiguration String statement configuration.
-
subprocess_if_recommended:
bool= True Use the subprocess mode if the SUT analysis recommends it based on used C extension modules.
-
test_case_output:
TestCaseOutputConfiguration Configuration for how test cases should be output.
-
test_creation:
TestCreationConfiguration Test creation configuration.
-
to_cover:
ToCoverConfiguration Configuration of which code elements are included or excluded as coverage goals.
-
type_inference:
TypeInferenceConfiguration Type inference configuration.
-
filesystem_isolation:
- class pynguin.configuration.CoverageMetric(value)[source]
The different available coverage metrics available for optimisation.
- BRANCH = 'BRANCH'
Calculate how many of the possible branches in the code were executed
- CHECKED = 'CHECKED'
Calculate how many of the possible lines in the code are checked by an assertion.
- LINE = 'LINE'
Calculate how many of the possible lines in the code were executed
- class pynguin.configuration.ExportStrategy(value)[source]
Contains all available export strategies.
These strategies allow to export the generated test cases in different styles, such as the style of the PyTest framework. Setting the value to NONE will prevent exporting of the generated test cases (only reasonable for benchmarking, though).
- NONE = 'NONE'
Do not export test cases at all.
- PY_TEST = 'PY_TEST'
Export tests in the style of the PyTest framework.
- class pynguin.configuration.GeneratorSelectionConfiguration(generator_selection_algorithm=Selection.RANK_SELECTION, generator_selection_bias=1.7, generator_any_distance=30, generator_not_constructor_penalty=10.0, generator_param_penalty=1.0, generator_hierarchy_penalty=1.0, generator_any_type_penalty=100.0)[source]
Configuration related to selecting a generator for a certain type.
-
generator_any_distance:
int= 30 The distance to and from the any type to any other type in the type hierarchy. As the any type is a super- and subtype of all type but it is most likely not the type we want, we want to punish it in the type selection process.
-
generator_any_type_penalty:
float= 100.0 Penalty for selecting a generator that returns only Any. While Any is always a valid type, we still want to avoid it as a generator.
-
generator_hierarchy_penalty:
float= 1.0 Penalty for the distance between the generators type and the desired type. The penalty is multiplied with the distance in the type hierarchy.
-
generator_not_constructor_penalty:
float= 10.0 Penalty for selecting a generator that is not a __init__ method.
-
generator_any_distance:
- class pynguin.configuration.LLMConfiguration(api_key='', model_name='gpt-4o-mini', llm_url='', temperature=0.8, hybrid_initial_population=False, llm_test_case_percentage=0.5, enable_response_caching=False, call_llm_for_uncovered_targets=False, coverage_threshold=1, call_llm_on_stall_detection=False, max_plateau_len=25, max_llm_interventions=1)[source]
Configuration for the LLM.
-
call_llm_for_uncovered_targets:
bool= False Whether to call the LLM for the uncovered targets initially.
-
call_llm_on_stall_detection:
bool= False Whether to call the LLM for the uncovered targets in coverage stalls.
-
coverage_threshold:
float= 1 The coverage threshold when to call the LLM for low-coverage targets. The value must be from [0.0, 1.0].
-
hybrid_initial_population:
bool= False Whether to include the LLM test cases in the initial population.
-
call_llm_for_uncovered_targets:
- class pynguin.configuration.LocalSearchConfiguration(local_search=True, local_search_same_datatype=True, local_search_different_datatype=False, local_search_llm=False, local_search_primitives=True, local_search_collections=False, local_search_complex_objects=False, local_search_probability=0.02, local_search_time=5000, ls_int_delta_increasing_factor=2, ls_string_random_mutation_count=10, ls_random_parametrized_statement_call_count=10, ls_max_different_type_mutations=10, ls_different_type_primitive_probability=0.3, ls_different_type_collection_probability=0.3, ls_dict_max_insertions=10, ls_llm_whole_module=False)[source]
Configurations for local search.
-
local_search_collections:
bool= False Toggles if local search for collection types is enabled or not
-
local_search_complex_objects:
bool= False Toggles if local search for complex object types is enabled or not
-
local_search_different_datatype:
bool= False Defines if local search with different datatypes is enabled or not
-
local_search_probability:
float= 0.02 Probability of starting local search on the specific candidate
-
local_search_same_datatype:
bool= True Defines if local search within same datatype is enabled or not
-
ls_different_type_collection_probability:
float= 0.3 Weight of generating collection statements when changing the statement type.
-
ls_different_type_primitive_probability:
float= 0.3 Weight of generating primitive statements when changing the statement type.
-
ls_int_delta_increasing_factor:
int= 2 The factor which defines how much the delta should increase for each iteration for integer local search.
-
ls_llm_whole_module:
bool= False Whether to provide the whole module or selected functions/methods to the LLM for context when performing llm local search.
-
local_search_collections:
- class pynguin.configuration.MIOConfiguration(initial_config=<factory>, focused_config=<factory>, exploitation_starts_at_percent=0.5)[source]
Configuration that is specific to the MIO approach.
-
exploitation_starts_at_percent:
float= 0.5 Percentage ]0,1] of search budget after which exploitation is activated, i.e., switching to focused phase.
-
focused_config:
MIOPhaseConfiguration Configuration to use in focused phase
-
initial_config:
MIOPhaseConfiguration Configuration to use before focused phase.
-
exploitation_starts_at_percent:
- class pynguin.configuration.MIOPhaseConfiguration(number_of_tests_per_target, random_test_or_from_archive_probability, number_of_mutations)[source]
Configuration for a phase of MIO.
- class pynguin.configuration.Minimization(test_case_minimization_strategy=MinimizationStrategy.CASE, test_case_minimization_direction=MinimizationDirection.BACKWARD)[source]
Configuration for test case minimization.
-
test_case_minimization_direction:
MinimizationDirection= 'BACKWARD' Direction to apply for minimizing test cases.
-
test_case_minimization_strategy:
MinimizationStrategy= 'CASE' Strategy to apply for minimizing test cases to remove redundant statements while preserving fitness.
-
test_case_minimization_direction:
- class pynguin.configuration.MinimizationDirection(value)[source]
Directions for test case minimization.
Either start with the first statement and try removing it and all forward dependent statements, or start with the last statement and try removing it and all backward dependent statements.
- BACKWARD = 'BACKWARD'
Apply backward minimization, which removes statements from the end to the beginning.
- FORWARD = 'FORWARD'
Apply forward minimization, which removes statements from the beginning to the end.
- class pynguin.configuration.MinimizationStrategy(value)[source]
Different strategies for minimizing test cases.
- CASE = 'CASE'
Apply minimization at the test case level.
- COMBINED = 'COMBINED'
Apply minimization at the test case level but check against all test cases in the suite.
- NONE = 'NONE'
Do not apply any minimization.
- SUITE = 'SUITE'
Apply minimization at the test suite level, i.e., remove entire test cases that do not contribute to the coverage of the module under test.
- class pynguin.configuration.MutationStrategy(value)[source]
Different strategies for creating mutants.
Only respected when using the MUTATION_ANALYSIS approach for assertion generation.
- BETWEEN_OPERATORS = 'BETWEEN_OPERATORS'
Higher order mutation strategy BetweenOperators. (cf. Mateo et al. Validating Second-Order Mutation at System Level. Article. IEEE Transactions on SE 39.4 2013)
- EACH_CHOICE = 'EACH_CHOICE'
Higher order mutation strategy EachChoice. (cf. Mateo et al. Validating Second-Order Mutation at System Level. Article. IEEE Transactions on SE 39.4 2013)
- FIRST_ORDER_MUTANTS = 'FIRST_ORDER_MUTANTS'
Generate first order mutants.
- FIRST_TO_LAST = 'FIRST_TO_LAST'
Higher order mutation strategy FirstToLast. (cf. Mateo et al. Validating Second-Order Mutation at System Level. Article. IEEE Transactions on SE 39.4 2013)
- RANDOM = 'RANDOM'
Higher order mutation strategy Random. (cf. Mateo et al. Validating Second-Order Mutation at System Level. Article. IEEE Transactions on SE 39.4 2013)
- class pynguin.configuration.PynguinMLConfiguration(ml_testing_enabled=False, constraints_path='', dtype_mapping_path='', constructor_function='', constructor_function_parameter='', max_ndim=4, max_shape_dim=4, ignore_constraints_probability=0.25)[source]
Configurations for PynguinML, specifically for machine learning API testing.
-
constructor_function:
str= '' Optional constructor function to build tensors (e.g., torch.tensor or tensorflow.convert_to_tensor). Must accept a np.ndarray as input. Note: Also set ‘constructor_function_parameter’ to specify which parameter receives the np.ndarray.
-
constructor_function_parameter:
str= '' Name of the parameter in the constructor function that receives the np.ndarray. Must be set when ‘constructor_function’ is specified.
-
dtype_mapping_path:
str= '' Path to a YAML/JSON file that maps library-specific datatypes to NumPy datatypes. Used by PynguinML for input generation. Specify only valid NumPy dtypes without the “np.” prefix. Example: “torch.int32” -> “int32”.
-
ignore_constraints_probability:
float= 0.25 Probability of ignoring constraints and falling back to Pynguin’s default behavior when constructing statements.
-
max_ndim:
int= 4 Maximum number of dimensions of the tensors. If set too big, it can cause memory errors due to large tensor sizes.
-
constructor_function:
- class pynguin.configuration.RandomConfiguration(max_sequence_length=10, max_sequences_combined=10)[source]
Configuration that is specific to the RANDOM approach.
- class pynguin.configuration.SearchAlgorithmConfiguration(min_initial_tests=1, max_initial_tests=10, population=10, chromosome_length=48, chop_max_length=True, elite=1, crossover_rate=0.648, test_insertion_probability=0.1, test_delete_probability=0.3333333333333333, test_change_probability=0.3333333333333333, test_insert_probability=0.3333333333333333, statement_insertion_probability=0.5, random_perturbation=0.2, change_parameter_probability=0.1, tournament_size=4, rank_bias=1.68, selection=Selection.RANK_SELECTION, use_archive=False, filter_covered_targets_from_test_cluster=False, number_of_mutations=3)[source]
General configuration for search algorithms.
-
change_parameter_probability:
float= 0.1 Probability of replacing parameters when mutating a method or constructor statement in a test case. Expects values in [0,1]
-
filter_covered_targets_from_test_cluster:
bool= False Focus search by filtering out elements from the test cluster when they are fully covered.
-
random_perturbation:
float= 0.2 Probability to replace a primitive with a random new value rather than adding a delta.
-
statement_insertion_probability:
float= 0.5 Initial probability of inserting a new statement in a test case
-
test_change_probability:
float= 0.3333333333333333 Probability of changing statements during mutation
-
test_delete_probability:
float= 0.3333333333333333 Probability of deleting statements during mutation
-
test_insert_probability:
float= 0.3333333333333333 Probability of inserting new statements during mutation
-
change_parameter_probability:
- class pynguin.configuration.SeedingConfiguration(seed=1780383204402602139, constant_seeding=True, initial_population_seeding=False, initial_population_data='', seeded_testcases_reuse_probability=0.9, initial_population_mutations=0, dynamic_constant_seeding=True, seeded_primitives_reuse_probability=0.2, seeded_dynamic_values_reuse_probability=0.6, seed_from_archive=False, seed_from_archive_probability=0.2, seed_from_archive_mutations=3, max_dynamic_length=1000, max_dynamic_pool_size=50)[source]
Configuration related to seeding.
-
constant_seeding:
bool= True Should the generator use a static constant seeding technique to improve constant generation?
-
initial_population_data:
str= '' The path to the file with the pre-existing tests. The path has to include the file itself.
-
initial_population_mutations:
int= 0 Number of how often the testcases collected by initial population seeding should be mutated to promote diversity
-
initial_population_seeding:
bool= False Should the generator use previously existing testcases to seed the initial population?
-
max_dynamic_length:
int= 1000 Maximum length of strings/bytes that should be stored in the dynamic constant pool.
-
max_dynamic_pool_size:
int= 50 Maximum number of constants of the same type that should be stored in the dynamic constant pool.
-
seed:
int= 1780383204402602139 A predefined seed value for the random number generator that is used.
-
seed_from_archive:
bool= False When sampling new test cases reuse some from the archive, if one is used.
-
seed_from_archive_probability:
float= 0.2 Instead of creating a new test case, reuse a covering solution from the archive, iff an archive is used.
-
seeded_dynamic_values_reuse_probability:
float= 0.6 Probability of using dynamically seeded values when a primitive seeded value will be used.
-
constant_seeding:
- class pynguin.configuration.Selection(value)[source]
Different selection algorithms to select from.
- RANDOM_SELECTION = 'RANDOM_SELECTION'
Random selection.
- RANK_SELECTION = 'RANK_SELECTION'
Rank selection.
- TOURNAMENT_SELECTION = 'TOURNAMENT_SELECTION'
Tournament selection. Use tournament_size to set size.
- class pynguin.configuration.StatisticsBackend(value)[source]
The different available statistics backends to write statistics.
- CONSOLE = 'CONSOLE'
Write statistics to the standard out.
- CSV = 'CSV'
Write statistics to a CSV file.
- NONE = 'NONE'
Do not write any statistics.
- class pynguin.configuration.StatisticsOutputConfiguration(report_dir='pynguin-report', statistics_backend=StatisticsBackend.CSV, timeline_interval=1000000000, timeline_interpolation=True, coverage_metrics=<factory>, output_variables=<factory>, configuration_id='', run_id='', project_name='', create_coverage_report=False, type_guess_top_n=10, store_test_before_execution=False)[source]
Configuration related to output.
-
configuration_id:
str= '' Label that identifies the used configuration of Pynguin. This is only done when running experiments.
-
coverage_metrics:
list[CoverageMetric] List of coverage metrics that are optimised during the search
-
create_coverage_report:
bool= False Create a coverage report for the tested module. This can be helpful to find hard to cover parts because Pynguin measures coverage on bytecode level which might yield different results when compared with other tools, e.g., Coverage.py.
-
project_name:
str= '' Label that identifies the project name of Pynguin. This is useful when running experiments.
-
run_id:
str= '' Id of the cluster run. Useful for finding the log entries that belong to a certain result.
-
statistics_backend:
StatisticsBackend= 'CSV' Which backend to use to collect data
-
store_test_before_execution:
bool= False When enabled, each test case is written to a file before execution and removed after successful completion. If a test causes a crash, the file remains. Use with caution: Converting pynguin internal representation to a pytest test case and writing it to a file is expensive and leads to lower iterations/coverage.
-
configuration_id:
- class pynguin.configuration.StoppingConfiguration(maximum_search_time=-1, maximum_test_executions=-1, maximum_statement_executions=-1, maximum_slicing_time=600, maximum_iterations=-1, maximum_test_execution_timeout=5, maximum_coverage=100, maximum_coverage_plateau=-1, minimum_coverage=100, minimum_plateau_iterations=-1, maximum_memory=3000, test_execution_time_per_statement=1)[source]
Configuration related to when Pynguin should stop.
Note that these are mostly soft-limits rather than hard limits, because the search algorithms only check the condition at the start of each algorithm iteration.
-
maximum_coverage:
int= 100 The maximum percentage of coverage after which the generation shall stop.
-
maximum_coverage_plateau:
int= -1 Maximum number of algorithm iterations without coverage change before the algorithms stops.
-
maximum_memory:
int= 3000 Maximum memory usage in MB after which the generation shall stop. Expects values in MB greater than 0 of -1 to disable the check.
-
maximum_test_execution_timeout:
int= 5 The maximum time (in seconds) after which a test case times out.
-
minimum_coverage:
int= 100 Minimum coverage for the plateau-based stopping condition. Expects values larger than 0 but less than 100 to activate the stopping condition; also requires the setting of minimum_plateau_iterations.
-
maximum_coverage:
- class pynguin.configuration.StringStatementConfiguration(random_string_weight=0.3, faker_string_weight=0.3, fandango_string_weight=0.4, fandango_faker_string_weight=0.0)[source]
Configuration related to string statements.
-
faker_string_weight:
float= 0.3 Probability use the Faker generator for string statement generation.
-
fandango_faker_string_weight:
float= 0.0 Probability use the Fandango + Faker generator for string statement generation.
-
faker_string_weight:
- class pynguin.configuration.SubtypeInferenceStrategy(value)[source]
The different available type-inference strategies.
- NONE = 'NONE'
Do not infer subtypes.
- STRING = 'STRING'
Infer subtypes for strings.
- class pynguin.configuration.TestCaseOutputConfiguration(output_path, crash_path='', export_strategy=ExportStrategy.PY_TEST, max_length_test_case=2500, assertion_generation=AssertionGenerator.MUTATION_ANALYSIS, allow_stale_assertions=False, mutation_strategy=MutationStrategy.FIRST_ORDER_MUTANTS, mutation_order=1, post_process=True, minimization=<factory>, float_precision=0.01, format_with_black=True, no_xfail=False)[source]
Configuration related to test case output.
-
allow_stale_assertions:
bool= False Allow assertion on things that did not change between statement executions.
-
assertion_generation:
AssertionGenerator= 'MUTATION_ANALYSIS' The generator that shall be used for assertion generation.
-
crash_path:
str= '' Path to an output folder for the generated test cases that caused a crash. Only works when running in a subprocess. If set to “”, the are stored in the output_path.
-
export_strategy:
ExportStrategy= 'PY_TEST' The export strategy determines for which test-runner system the generated tests should fit.
-
max_length_test_case:
int= 2500 The maximum number of statement in as test case (normal + assertion statements)
-
minimization:
Minimization Strategy to apply for minimizing test cases.
-
mutation_order:
int= 1 The order of the generated higher order mutants in the mutation analysis assertion generation method.
-
mutation_strategy:
MutationStrategy= 'FIRST_ORDER_MUTANTS' The strategy that shall be used for creating mutants in the mutation analysis assertion generation method.
-
allow_stale_assertions:
- class pynguin.configuration.TestCreationConfiguration(max_recursion=10, max_delta=20, max_int=2048, string_length=20, bytes_length=20, collection_size=5, primitive_reuse_probability=0.5, object_reuse_probability=0.9, none_weight=1, any_weight=5, original_type_weight=5, type_tracing_weight=10, type_tracing_kept_guesses=2, wrap_var_param_type_probability=0.7, negate_type=0.1, skip_optional_parameter_probability=0.7, max_attempts=1000, insertion_uut=0.5, max_size=100, use_random_object_for_call=0.1)[source]
Configuration related to test creation.
-
any_weight:
float= 5 Weight to use Any as parameter type during test generation. Expects values > 0.
-
negate_type:
float= 0.1 When inferring a type from proxies, it may also be desirable to negate the chosen type, e.g., such that an instance check or a getattr() evaluate to False. Expects values in [0,1]
-
none_weight:
float= 1 Weight to use None as parameter type during test generation. Expects values > 0.
-
object_reuse_probability:
float= 0.9 Probability to reuse an existing object in a test case, if available. Expects values in [0,1]
-
original_type_weight:
float= 5 Weight to use the originally annotated type as parameter type during test generation. Expects values > 0.
-
primitive_reuse_probability:
float= 0.5 Probability to reuse an existing primitive in a test case, if available. Expects values in [0,1]
-
skip_optional_parameter_probability:
float= 0.7 Probability to skip an optional parameter, i.e., do not fill such a parameter.
-
type_tracing_kept_guesses:
int= 2 Amount of kept recently guessed types per parameter, when type tracing is used.
-
type_tracing_weight:
float= 10 Weight to use the type guessed from type tracing as parameter type during test generation. Expects values > 0.
-
any_weight:
- class pynguin.configuration.ToCoverConfiguration(only_cover=<factory>, no_cover=<factory>, enable_inline_pynguin_no_cover=True, enable_inline_pragma_no_cover=True)[source]
Configuration of which code elements are included or excluded as coverage goals.
Pynguin instruments only the respective parts of the SUT module for coverage measurement. All configuration options are resolved as SUT line numbers which must not overlap (‘only’ and ‘no’ at the same time).
- class pynguin.configuration.TypeInferenceConfiguration(type_inference_strategy=TypeInferenceStrategy.TYPE_HINTS, type_tracing=0.0, subtype_inference=SubtypeInferenceStrategy.NONE, type_tracing_subtype_weight=0.3, type_tracing_argument_type_weight=0.5, type_tracing_attribute_weight=0.2, typeevalpy_json_path='')[source]
Configuration related to type inference.
-
subtype_inference:
SubtypeInferenceStrategy= 'NONE' The strategy for subtype-inference that shall be used.
-
type_inference_strategy:
TypeInferenceStrategy= 'TYPE_HINTS' The strategy for type-inference that shall be used
-
type_tracing:
bool|float= 0.0 Probability to trace usage of parameters with unknown types to improve type guesses during test execution. Type tracing requires a separate second. The value should be a float in [0,1]. Boolean is kept for backwards compatibility as Python internally converts True to 1.0 and False to 0.0 anyways.
-
type_tracing_argument_type_weight:
float= 0.5 Weight for selecting the argument type inference strategy for type selection during type tracing.
-
type_tracing_attribute_weight:
float= 0.2 Weight for selecting the attribute table inference strategy for type selection during type tracing.
-
subtype_inference:
- class pynguin.configuration.TypeInferenceStrategy(value)[source]
The different available type-inference strategies.
- LLM = 'LLM'
Use an LLM to infer types for the module under test.
- LLM_WITH_SUBTYPES = 'LLM_WITH_SUBTYPES'
Use an LLM to infer types and subtypes for the module under test.
- NONE = 'NONE'
Ignore any type information given in the module under test.
- TYPEEVALPY = 'TYPEEVALPY'
Use TypeEvalPy data only for type inference.
- TYPE_HINTS = 'TYPE_HINTS'
Use type information from type hints in the module under test.
pynguin.generator
Pynguin is an automated unit test generation framework for Python.
The framework generates unit tests for a given Python module. For this it supports various approaches, such as a random approach, similar to Randoop or a whole-suite approach, based on a genetic algorithm, as implemented in EvoSuite. The framework allows to export test suites in various styles, i.e., using the unittest library from the Python standard library or tests in the style used by the PyTest framework.
Pynguin is supposed to be used as a standalone command-line application but it can also be used as a library by instantiating this class directly.
- class pynguin.generator.ReturnCode(value)[source]
Return codes for Pynguin to signal result.
- FINAL_METRICS_TRACKING_FAILED = 3
Symbolises that the final metrics tracking failed.
- NO_TESTS_GENERATED = 2
Symbolises that no test could be generated.
- OK = 0
Symbolises that the execution ended as expected.
- SETUP_FAILED = 1
Symbolises that the execution failed in the setup phase.
- pynguin.generator.run_pynguin()[source]
Run the test generation.
The result of the test generation is indicated by the resulting ReturnCode.
- Return type:
- Returns:
See ReturnCode.
- Raises:
ConfigurationException – In case the configuration is illegal
- pynguin.generator.set_configuration(configuration)[source]
Initialises the test generator with the given configuration.
- Parameters:
configuration (
Configuration) – The configuration to use.- Return type:
pynguin.analyses.module
Provides analyses for the subject module, based on the module and its AST.
- class pynguin.analyses.module.CallableData(accessible, tree, description, cyclomatic_complexity)[source]
Provides all information on callables.
While the accessible is available for every callable, the other fields are only filled for methods that are available in (Python) source code because their information is retrieved from the abstract syntax tree.
- accessible
the accessible object itself
- tree
the AST of the callable, if any
- description
the function description of the callable, if any
- cyclomatic_complexity
the McCabe cyclomatic complexity of the callable, if any
- class pynguin.analyses.module.FilteredModuleTestCluster(delegate, archive, subject_properties, targets)[source]
A test cluster wrapping another test cluster.
Delegates most methods to the wrapped delegate. This cluster filters out accessible objects under test that are already fully covered, in order to focus the search on areas that are not yet fully covered.
- property accessible_objects_under_test: OrderedSet[GenericAccessibleObject]
Provides all accessible objects under test.
- add_accessible_object_under_test(objc, data)[source]
Add accessible object to the objects under test.
- Parameters:
objc (
GenericAccessibleObject) – The accessible objectdata (
CallableData) – The function-description data
- Return type:
- add_generator(generator)[source]
Add the given accessible as a generator.
- Parameters:
generator (
GenericAccessibleObject) – The accessible object- Return type:
- add_modifier(typ, obj)[source]
Add a modifier.
A modifier is something that can be used to modify the given type, for example, a method.
- property function_data_for_accessibles: dict[GenericAccessibleObject, CallableData]
Provides all function data for all accessibles.
- property generators: dict[ProperType, OrderedSet[GenericAccessibleObject]]
Provides all available generators.
- get_all_generatable_types()[source]
Provides all types that can be generated.
This includes primitives and collections.
- Returns:
DAR202
- Return type:
A list of all types that can be generated # noqa
- get_generators_for(typ)[source]
Retrieve all known generators for the given type.
- Parameters:
typ (
ProperType) – The type we want to have the generators for- Return type:
OrderedSet[GenericAccessibleObject]- Returns:
The set of all generators for that type.
- get_modifiers_for(typ)[source]
Get all known modifiers for a type.
- Parameters:
typ (
ProperType) – The type- Returns:
DAR202
- Return type:
The set of all accessibles that can modify the type # noqa
- get_random_accessible()[source]
Provides a random accessible of the unit under test.
- Returns:
DAR202
- Return type:
A random accessible, or None if there is none # noqa
- get_random_call_for(typ)[source]
Get a random modifier for the given type.
- Parameters:
typ (
ProperType) – The type- Returns:
DAR202
- Return type:
A random modifier for that type # noqa
- Raises:
ConstructionFailedException – if no modifiers for the type exist# noqa: DAR402
- property modifiers: dict[TypeInfo, OrderedSet[GenericAccessibleObject]]
Provides all available modifiers.
- num_accessible_objects_under_test()[source]
Provide the number of accessible objects under test.
Useful to check whether there is even something to test.
- Return type:
- on_target_covered(target)[source]
A callback function to get informed by an archive when a target is covered.
- Parameters:
target (
TestCaseFitnessFunction) – The newly covered target- Return type:
- select_concrete_type(typ)[source]
Select a concrete type from the given type.
This is required, for example, when handling union types. Currently, only unary types, Any, and Union are handled.
- Parameters:
typ (
ProperType) – An optional type- Returns:
DAR202
- Return type:
An optional type # noqa
- track_statistics_values(tracking_fun)[source]
Track statistics values from the test cluster and its items.
- property type_system: TypeSystem
Provides the inheritance graph.
- update_parameter_knowledge(accessible, param_name, knowledge)[source]
Update the knowledge about the parameter of the given accessible.
- Parameters:
accessible (
GenericCallableAccessibleObject) – the accessible that was observed.param_name (
str) – the parameter name for which we have new information.knowledge (
UsageTraceNode) – the new information.
- Return type:
- update_return_type(accessible, new_type)[source]
Update the return for the given accessible to the new seen type.
- Parameters:
accessible (
GenericCallableAccessibleObject) – the accessible that was observednew_type (
ProperType) – the new return type
- Return type:
- class pynguin.analyses.module.MLCallableData(parameters, generation_order)[source]
Provides ML-specific information on callables.
- parameters
A dictionary of parameters, if any
- generation_order
The generation order of the callable (can be empty)
- class pynguin.analyses.module.ModuleTestCluster(linenos)[source]
A test cluster for a module.
Contains all methods/constructors/functions and all required transitive dependencies.
- property accessible_objects_under_test: OrderedSet[GenericAccessibleObject]
Provides all accessible objects under test.
- add_accessible_object_under_test(objc, data)[source]
Add accessible object to the objects under test.
- Parameters:
objc (
GenericAccessibleObject) – The accessible objectdata (
CallableData) – The function-description data
- Return type:
- add_generator(generator)[source]
Add the given accessible as a generator.
- Parameters:
generator (
GenericAccessibleObject) – The accessible object- Return type:
- add_modifier(typ, obj)[source]
Add a modifier.
A modifier is something that can be used to modify the given type, for example, a method.
- property function_data_for_accessibles: dict[GenericAccessibleObject, CallableData]
Provides all function data for all accessibles.
- property generators: dict[ProperType, OrderedSet[GenericAccessibleObject]]
Provides all available generators.
- get_all_generatable_types()[source]
Provides all types that can be generated.
This includes primitives and collections.
- Returns:
DAR202
- Return type:
A list of all types that can be generated # noqa
- get_generators_for(typ)[source]
Retrieve all known generators for the given type.
- Parameters:
typ (
ProperType) – The type we want to have the generators for- Return type:
OrderedSet[GenericAccessibleObject]- Returns:
The set of all generators for that type.
- get_modifiers_for(typ)[source]
Get all known modifiers for a type.
- Parameters:
typ (
ProperType) – The type- Returns:
DAR202
- Return type:
The set of all accessibles that can modify the type # noqa
- get_random_accessible()[source]
Provides a random accessible of the unit under test.
- Returns:
DAR202
- Return type:
A random accessible, or None if there is none # noqa
- get_random_call_for(typ)[source]
Get a random modifier for the given type.
- Parameters:
typ (
ProperType) – The type- Returns:
DAR202
- Return type:
A random modifier for that type # noqa
- Raises:
ConstructionFailedException – if no modifiers for the type exist# noqa: DAR402
- property modifiers: dict[TypeInfo, OrderedSet[GenericAccessibleObject]]
Provides all available modifiers.
- num_accessible_objects_under_test()[source]
Provide the number of accessible objects under test.
Useful to check whether there is even something to test.
- Return type:
- select_concrete_type(typ)[source]
Select a concrete type from the given type.
This is required, for example, when handling union types. Currently, only unary types, Any, and Union are handled.
- Parameters:
typ (
ProperType) – An optional type- Returns:
DAR202
- Return type:
An optional type # noqa
- track_statistics_values(tracking_fun)[source]
Track statistics values from the test cluster and its items.
- property type_system: TypeSystem
Provides the type system.
- Returns:
The type system.
- update_parameter_knowledge(accessible, param_name, knowledge)[source]
Update the knowledge about the parameter of the given accessible.
- Parameters:
accessible (
GenericCallableAccessibleObject) – the accessible that was observed.param_name (
str) – the parameter name for which we have new information.knowledge (
UsageTraceNode) – the new information.
- Return type:
- update_return_type(accessible, new_type)[source]
Update the return for the given accessible to the new seen type.
- Parameters:
accessible (
GenericCallableAccessibleObject) – the accessible that was observednew_type (
ProperType) – the new return type
- Return type:
- class pynguin.analyses.module.SignatureInfo(annotated_parameter_types=<factory>, guessed_parameter_types=<factory>, partial_type_matches=<factory>, annotated_return_type=None, recorded_return_type=None)[source]
Another utility class to group information per callable.
- class pynguin.analyses.module.TestCluster[source]
Interface for a test cluster.
- abstract property accessible_objects_under_test: OrderedSet[GenericAccessibleObject]
Provides all accessible objects under test.
- abstract add_accessible_object_under_test(objc, data)[source]
Add accessible object to the objects under test.
- Parameters:
objc (
GenericAccessibleObject) – The accessible objectdata (
CallableData) – The function-description data
- Return type:
- abstract add_generator(generator)[source]
Add the given accessible as a generator.
- Parameters:
generator (
GenericAccessibleObject) – The accessible object- Return type:
- abstract add_modifier(typ, obj)[source]
Add a modifier.
A modifier is something that can be used to modify the given type, for example, a method.
- abstract property function_data_for_accessibles: dict[GenericAccessibleObject, CallableData]
Provides all function data for all accessibles.
- abstract property generators: dict[ProperType, OrderedSet[GenericAccessibleObject]]
Provides all available generators.
- abstract get_all_generatable_types()[source]
Provides all types that can be generated.
This includes primitives and collections.
- Returns:
DAR202
- Return type:
A list of all types that can be generated # noqa
- abstract get_generators_for(typ)[source]
Retrieve all known generators for the given type.
- Parameters:
typ (
ProperType) – The type we want to have the generators for- Return type:
OrderedSet[GenericAccessibleObject]- Returns:
The set of all generators for that type.
- abstract get_ml_data_for(generic_accessible)[source]
Provides ML data for a accessible.
- Return type:
- abstract get_modifiers_for(typ)[source]
Get all known modifiers for a type.
- Parameters:
typ (
ProperType) – The type- Returns:
DAR202
- Return type:
The set of all accessibles that can modify the type # noqa
- abstract get_random_accessible()[source]
Provides a random accessible of the unit under test.
- Returns:
DAR202
- Return type:
A random accessible, or None if there is none # noqa
- abstract get_random_call_for(typ)[source]
Get a random modifier for the given type.
- Parameters:
typ (
ProperType) – The type- Returns:
DAR202
- Return type:
A random modifier for that type # noqa
- Raises:
ConstructionFailedException – if no modifiers for the type exist# noqa: DAR402
- abstract property modifiers: dict[TypeInfo, OrderedSet[GenericAccessibleObject]]
Provides all available modifiers.
- abstract num_accessible_objects_under_test()[source]
Provide the number of accessible objects under test.
Useful to check whether there is even something to test.
- Return type:
- abstract select_concrete_type(typ)[source]
Select a concrete type from the given type.
This is required, for example, when handling union types. Currently, only unary types, Any, and Union are handled.
- Parameters:
typ (
ProperType) – An optional type- Returns:
DAR202
- Return type:
An optional type # noqa
- abstract track_statistics_values(tracking_fun)[source]
Track statistics values from the test cluster and its items.
- abstract property type_system: TypeSystem
Provides the inheritance graph.
- abstract update_parameter_knowledge(accessible, param_name, knowledge)[source]
Update the knowledge about the parameter of the given accessible.
- Parameters:
accessible (
GenericCallableAccessibleObject) – the accessible that was observed.param_name (
str) – the parameter name for which we have new information.knowledge (
UsageTraceNode) – the new information.
- Return type:
- abstract update_return_type(accessible, new_type)[source]
Update the return for the given accessible to the new seen type.
- Parameters:
accessible (
GenericCallableAccessibleObject) – the accessible that was observednew_type (
ProperType) – the new return type
- Return type:
- class pynguin.analyses.module.TypeGuessingStats(number_of_constructors=0, signature_infos=<factory>)[source]
Class to gather some type guessing related statistics.
- pynguin.analyses.module.analyse_module(parsed_module, type_inference_strategy=TypeInferenceStrategy.TYPE_HINTS)[source]
Analyses a module to build a test cluster.
- Parameters:
parsed_module (
_ModuleParseResult) – The parsed moduletype_inference_strategy (
TypeInferenceStrategy) – The type inference strategy to use.
- Return type:
- Returns:
A test cluster for the module
- pynguin.analyses.module.collect_provider_metrics(typ_provider)[source]
Collects metrics from the given type inference provider.
currently, this only works for LLM-based providers.
When using an LLM-based provider, collect the raw inferred parameter strings per callable and the annotated parameter strings as JSON and store in the LLMInferredSignatures runtime variable.
Other providers default all metrics to zero.
- pynguin.analyses.module.generate_test_cluster(module_name, type_inference_strategy=TypeInferenceStrategy.TYPE_HINTS)[source]
Generates a new test cluster from the given module.
- Parameters:
module_name (
str) – The name of the root moduletype_inference_strategy (
TypeInferenceStrategy) – Which type-inference strategy to use
- Return type:
- Returns:
A new test cluster for the given module
- pynguin.analyses.module.get_type_provider(type_inference_strategy, module, type_system)[source]
Get the initialised inference provider for the given strategy.
- Parameters:
type_inference_strategy (
TypeInferenceStrategy) – The type inference strategy to usemodule (
ModuleType) – The module to analyse (only needed for LLM-based inference)type_system (
TypeSystem) – The type system to use
- Return type:
InferenceProvider- Returns:
The type inference provider for the given strategy
- pynguin.analyses.module.import_module(module_name)[source]
Imports a module by name.
Unlike the built-in
importlib.import_module(), this function also supports importing module aliases.- Parameters:
module_name (
str) – The fully-qualified name of the module- Return type:
- Returns:
The imported module
- pynguin.analyses.module.parse_module(module_name)[source]
Parses a module and extracts its module-type and AST.
If the source code is not available it is not possible to build an AST. In this case the respective field of the
_ModuleParseResultwill contain the valueNone. This is the case, for example, for modules written in native code, for example, in C.- Parameters:
module_name (
str) – The fully-qualified name of the module- Return type:
_ModuleParseResult- Returns:
A tuple of the imported module type and its optional AST
- pynguin.analyses.module.read_module_ast(module_path, module_name)[source]
Reads the AST of the module and returns it along with its source code.
- Parameters:
- Raises:
OSError – if the module file cannot be read.
AstroidError – if an error occurs during the creation of the AST.
- Return type:
- Returns:
A tuple containing the AST and the source code.
pynguin.analyses.typesystem
Provides analyses for a module’s type information.
- class pynguin.analyses.typesystem.AnyType[source]
The Any Type.
- accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
- class pynguin.analyses.typesystem.CSVString[source]
A string that represents comma-separated values.
Examples: “value1,value2,value3”, “itemA,itemB,itemC”.
- class pynguin.analyses.typesystem.EmailString[source]
A string that follows the general pattern of an email address.
Example: “name@domain.edu”.
- class pynguin.analyses.typesystem.HexadecimalString[source]
A string that represents a hexadecimal number.
Examples: “0x1A3F”, “1a3f”, “0XABCDEF”.
- class pynguin.analyses.typesystem.IPv4String[source]
A string that represents an IPv4 address.
Examples: “192.168.0.0”, “74.5.123.31”.
- class pynguin.analyses.typesystem.IPv6String[source]
A string that represents an IPv6 address.
Examples: “2001:0db8:85a3:0000:0000:8a2e:0370:7334”, “fe80::1ff:fe23:4567:890a”.
- class pynguin.analyses.typesystem.ISOColorString[source]
A string that represents a hexadecimal color code.
Examples: “#FFFFFF”, “#000000”, “#FF5733”.
- class pynguin.analyses.typesystem.ISODateString[source]
A string that represents a date in ISO 8601 format.
Examples: “2023-10-05”, “1999-12-31”.
- class pynguin.analyses.typesystem.ISOTimeString[source]
A string that represents a time in ISO 8601 format.
Examples: “14:30:00”, “23:59:59”.
- class pynguin.analyses.typesystem.InferredSignature(signature, original_return_type, original_parameters, type_system, parameters_for_statistics=<factory>, return_type_for_statistics=AnyType())[source]
Encapsulates the types inferred for a method.
- get_parameter_types(signature_memo)[source]
Get a possible type signature for the parameters.
This method may choose a random type signature, or return the original one or create one based on the observed knowledge.
- Parameters:
signature_memo (
dict[InferredSignature,dict[str,ProperType]]) – A memo that stores already chosen signatures, so that we don’t choose another signature in the same run. This is required for certain operations in the test factory to be consistent.- Return type:
- Returns:
A dict of chosen parameter types for each parameter.
- log_stats_and_guess_signature(is_constructor, callable_full_name, stats)[source]
Logs some statistics and creates a guessed signature.
Parameters annotated with Any could not be guessed.
- Parameters:
callable_full_name (
str) – The full, unique name of the callable.is_constructor (
bool) – does this signature to a constructor?stats (
TypeGuessingStats) – stats object to log to.
- Return type:
- class pynguin.analyses.typesystem.Instance(typ, args=None)[source]
An instance type of form C[T1, …, Tn].
C is a class. Args can be empty.
- accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
- class pynguin.analyses.typesystem.NamedDefaultDict[source]
A default dictionary that automatically creates nodes for keys.
Default dict which automatically creates a UsageTraceNode for each requested and non-existing key.
- class pynguin.analyses.typesystem.NoneType[source]
The None type.
- accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
- class pynguin.analyses.typesystem.NumericString[source]
A string that only contains numerical characters and an optional decimal point.
Examples: “123”, “123.45”, “0.001”
- class pynguin.analyses.typesystem.PhoneNumberString[source]
A string that represents a phone number.
Examples: “+1-800-555-1234”, “(123) 456-7890”.
- class pynguin.analyses.typesystem.ProperType[source]
Base class for all types. Might have to add another layer, like mypy’s Type?.
All subclasses of this class are immutable.
- abstract accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
- class pynguin.analyses.typesystem.SHA256String[source]
A string that represents a SHA-256 hash.
Examples: “e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855”.
- class pynguin.analyses.typesystem.StringSubtype(regex)[source]
A subtype of str determined by its regex.
TODO(lk): Add support to all visitors.
- accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
- class pynguin.analyses.typesystem.TupleType(args, *, unknown_size=False)[source]
Tuple type Tuple[T1, …, Tn].
Note that tuple is a special case and intentionally not Instance(TypeInfo(tuple)) because tuple is varargs generic.
- accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
- class pynguin.analyses.typesystem.TypeInfo(raw_type)[source]
A small wrapper around type, i.e., classes.
Corresponds 1:1 to a class.
- static get_dunder_value_from_type(typ, name)[source]
Get the dunder value with the given name from the given type.
If the given type has no dunder attribute with the given name, we fall back to using the type of the given typ (== a value in this case). This worked for the UnionType.
- static to_full_name(typ)[source]
Get the full name of the given type.
While type has a __name__, __qualname__ and __module__ attribute, UnionType does not. This caused a crash which is resolved by special handling of UnionType.
- Parameters:
typ – The type for which we want a full name.
- Return type:
- Returns:
The fully qualified name
- class pynguin.analyses.typesystem.TypeReprVisitor[source]
A simple visitor to create a repr from a proper type.
- visit_unsupported_type(left)[source]
Visit unsupported type.
- Parameters:
left (
Unsupported) – unsupported- Return type:
- Returns:
result of the visit
- class pynguin.analyses.typesystem.TypeStringVisitor[source]
A simple visitor to convert a proper type to a string.
- visit_unsupported_type(left)[source]
Visit unsupported type.
- Parameters:
left (
Unsupported) – unsupported- Return type:
- Returns:
result of the visit
- class pynguin.analyses.typesystem.TypeSystem[source]
Implements Pynguin’s internal type system.
Provides a simple inheritance graph relating various classes using their subclass relationships. Note that parents point to their children.
This is also the central system to store/handle type information.
- convert_type_hint(hint, unsupported=AnyType())[source]
Converts a type hint to a proper type.
Python’s builtin functionality makes handling types during runtime really hard, because 1) this is not intended to be used at runtime and 2) there are a lot of different notations, due to the constantly evolving type hint system. We also cannot easily use mypy’s type abstraction because it is 1) strongly encapsulated and not part of mypy’s public API and 2) is designed to be used for static type checking. This method tries to translate type hints into our own type abstraction in order to make handling types less painful.
This conversion is naive when compared to what sophisticated type checkers like mypy do, but it is hopefully sufficient for our purposes. This method only handles a very small subset of the types that we may encounter in the wild, but at least it allows use to better reason about types. This should be extended in the future to handle more cases.
- Parameters:
hint (
Any) – The type hintunsupported (
ProperType) – The type to use when encountering an unsupported type construct
- Return type:
- Returns:
A proper type.
- get_shortest_path_length(start, end)[source]
Get the shortest path length between two types.
I tried adding @functools.lru_cache to this function does not improve performance, because we cache subtype_distance anyway. I tried using a _shortest_path_length_cache[(start, end)] along with using shortest_path_length(graph, source), which returns all nodes reachable from start and its length. However, probably the overhead from caching and having many different starting nodes make this slower than just using shortest_path_length with a target node (which can also leverage the quicker bidirectional_shortest_path internally). I also tried to come up with an own variant of nx.single_shortest_path_length that would stop at the target node, thinking the overhead maybe comes form deeper traversal, but this did not achieve better performance either. Thus, I suggest we stick to the simple version.
- get_type_outside_of(klasses)[source]
Find a type that does not belong to the given types or any subclasses.
- infer_signature(method, type_hint_provider)[source]
Infers the method signature using the given type hint provider.
- Parameters:
- Return type:
- Returns:
The inference result
- infer_type_info(method, type_inference_provider)[source]
Infers the type information for a callable.
- Parameters:
method (
Callable) – The callable we try to infer type information fortype_inference_provider (
InferenceProvider) – The provider for type inference
- Return type:
- Returns:
The inference result
- is_maybe_subtype(left, right)[source]
Is ‘left’ maybe a subtype of ‘right’?
This is a more lenient check than is_subtype. Consider a function that returns tuple[str | int | bytes, str | int | bytes]. Strictly speaking, we cannot use such a value as an argument for a function that requires an argument of type tuple[int, int]. However, it may be possible that the returned value is tuple[int, int], in which case it does work. This check only differs from is_subtype in how it handles Unions. Instead of requiring every type to be a subtype, it is sufficient that one type of the Union is a subtype.
- Parameters:
left (
ProperType) – The left typeright (
ProperType) – The right type
- Return type:
- Returns:
True, if left may be a subtype of right.
- is_subtype(left, right)[source]
Is ‘left’ a subtype of ‘right’?
This check is more than incomplete, but it takes into account that anything is a subtype of AnyType.
See https://peps.python.org/pep-0483/ and https://peps.python.org/pep-0484/ for more details
- Parameters:
left (
ProperType) – The left typeright (
ProperType) – The right type
- Return type:
- Returns:
True, if left is a subtype of right.
- push_attributes_down()[source]
Pushes attributes down in hierarchy.
We don’t want to see attributes multiple times, e.g., in subclasses, so only the first class in the hierarchy which adds the attribute should have it listed as an attribute, i.e., when searching for a class with that attribute we only want to retrieve the top-most class(es) in the hierarchy which define it, and not every (sub)class that inherited it.
- Return type:
- subtype_distance(supertype, subtype)[source]
Computes the number of subclassing steps from the supertype to the subtype.
The number of subclassing steps is the shortest path length in the inheritance graph from the supertype to the subtype. The length from a type to itself is 0. If there is no path from the supertype to the subtype, i.e. if the supertype is not a supertype of the subtype, the method returns None. Similar to is_maybe_subtype, for unions it is sufficient that one type of the Union is a subtype and further the shortest path between all arguments of the Union is computed. See _SubtypeDistanceVisitor for special cases.
Examples
Assume (Super > Sub > SubSub). Super, Sub -> 1 Sub, Super -> None Super, Super -> 0 Super, SubSub -> 2
- Parameters:
supertype (
ProperType) – The more general type.subtype (
ProperType) – The more specific type.
- Return type:
- Returns:
The number of subclassing steps from left to right, or None if no path exists.
- to_type_info(typ)[source]
Find or create TypeInfo for the given type.
- Parameters:
typ – The raw type we want to convert.
- Return type:
- Returns:
A TypeInfo object.
- try_to_load_type(candidate, globs)[source]
Try to load the given type.
- Parameters:
candidate (
str) – The type to loadglobs – The globals that should be used for loading.
- Return type:
- Returns:
The loaded type or Any.
- wrap_var_param_type(typ, param_kind)[source]
Wrap parameter types.
Wrap the parameter type of
*argsand**kwargsin List[…] or Dict[str, …], respectively.- Parameters:
typ (
ProperType) – The type to be wrapped.param_kind – the kind of parameter.
- Return type:
- Returns:
The wrapped type, or the original type, if no wrapping is required.
- class pynguin.analyses.typesystem.TypeVisitor[source]
A type visitor.
Note that the parameter of the visit_* methods is called ‘left’, because it makes the implementations of _SubTypeVisitor and _MaybeSubTypeVisitor more clear and Python does not like changing the names of parameters in subclasses, thus we renamed them in this class.
- visit_string_subtype(left)[source]
Visit a string subtype.
- Parameters:
left (
StringSubtype) – string subtype- Return type:
TypeVar(T)- Returns:
Result of the visit
- abstract visit_unsupported_type(left)[source]
Visit unsupported type.
- Parameters:
left (
Unsupported) – unsupported- Return type:
TypeVar(T)- Returns:
result of the visit
- class pynguin.analyses.typesystem.URLString[source]
A string that represents a URL.
Examples: “http://example.com”, “https://www.domain.org/path?query=param”.
- class pynguin.analyses.typesystem.UUIDString[source]
A string that represents a UUID.
Examples: “123e4567-e89b-12d3-a456-426614174000”.
- class pynguin.analyses.typesystem.UnionType(items)[source]
The union type Union[T1, …, Tn] (at least one type argument).
- accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
- class pynguin.analyses.typesystem.Unsupported[source]
Marks an unsupported type in the type system.
Artificial type which represents a type that is currently not supported by our type abstraction. This is purely used for statistic purposes and should not be encountered during regular use.
- accept(visitor)[source]
Accept a type visitor.
- Parameters:
visitor (
TypeVisitor[TypeVar(T)]) – the visitor- Return type:
TypeVar(T)
pynguin.testcase.testcase
Provides an implementation for a test case.
- class pynguin.testcase.testcase.TestCase(test_cluster)[source]
An abstract base implementation for a test case.
Serves as an interface for test-case implementations
- abstract accept(visitor)[source]
Handles a test visitor.
- Parameters:
visitor (
TestCaseVisitor) – The test visitor to accept- Return type:
- abstract add_statement(statement, position=-1)[source]
Adds a new statement to the test case.
The optional position parameter specifies the position. If it is not given, the statement will be added to the end of the test case.
- Parameters:
statement (
Statement) – The new statementposition (
int) – The optional position where to put the statement
- Return type:
VariableReference|None
- Returns: # noqa: DAR202
The return value of the statement. Notice that the test might choose to modify the statement you inserted. You should use the returned variable reference and not use references. Can be None, if this statement does not create a variable.
- abstract add_variable_creating_statement(statement, position=-1)[source]
Overloaded version of add_statement that adds a statement.
- Parameters:
statement (
VariableCreatingStatement) – The new statementposition (
int) – The optional position where to put the statement
- Return type:
VariableReference
- Returns: # noqa: DAR202
The return value of the statement. Notice that the test might choose to modify the statement you inserted. You should use the returned variable reference and not use references.
- abstract contains(statement)[source]
Determines whether or not the test case contains a specific statement.
- Parameters:
statement (
Statement) – The statement to search in the test case- Returns:
DAR202
- Return type:
Whether or not the test case contains the statement # noqa
- get_all_objects(position)[source]
Get all objects that are defined up to the given position (exclusive).
- abstract get_assertions()[source]
Get all assertions that exist for this test case.
- Return type:
list[Assertion]
- abstract get_dependencies(var)[source]
Provides all variables on which var depends.
- Parameters:
var (
VariableReference) – the variable whose dependencies we are looking for.- Returns:
DAR202
- Return type:
a set of variables on which var depends on. # noqa
- abstract get_forward_dependencies(var)[source]
Provides all variables that depend on var.
- Parameters:
var (
VariableReference) – the variable for which we look for all dependent statements of- Returns:
DAR202
- Return type:
a set of variables that depend on var. # noqa
- get_objects(parameter_type, position)[source]
Provides a list of variable references satisfying a certain type.
If the position value is larger than the number of statements, only these statements will be considered. Otherwise, the first position statements of the test case will be considered.
If the type for which we search is not specified, all objects up to the given position are returned.
- Parameters:
parameter_type (
ProperType) – The type of the parameter we search references forposition (
int) – The position in the statement list until we search
- Return type:
list[VariableReference]- Returns:
A list of variable references satisfying the parameter type
- get_random_object(parameter_type, position)[source]
Get a random object of the given type up to the given position (exclusive).
- Parameters:
parameter_type (
ProperType) – the parameter typeposition (
int) – the position
- Return type:
VariableReference- Returns:
A random object of given type up to the given position
- Raises:
ConstructionFailedException – if no object could be found
- abstract get_statement(position)[source]
Provides access to a statement at a given position.
- Parameters:
position (
int) – The position of the statement in the test case- Returns:
DAR202
- Return type:
The statement at the position # noqa
- abstract has_statement(position)[source]
Check if there is a statement at the given position.
- Parameters:
position (
int) – The index of the statement- Returns:
DAR202
- Return type:
Whether or not there is a statement at the given position # noqa
- static positions_to_remove(statement, dependencies)[source]
Get the positions to remove and its forward dependencies in reverse order.
This is done to avoid index issues when removing multiple statements.
- abstract remove_statement(statement)[source]
Remove the given statement from this test case.
- Parameters:
statement (
Statement) – The statement to remove.- Return type:
- abstract remove_statement_with_forward_dependencies(statement)[source]
Removes the given statement along with all its forward dependencies.
- Parameters:
statement (
Statement) – The statement to remove- Return type:
- Returns:
A list of positions of statements that have been deleted
- Raises:
ValueError – If the statement is not contained in the test case
- abstract remove_with_forward_dependencies(position)[source]
Removes a statement at the given position along with all its forward dependencies.
- Parameters:
position (
int) – The position of the statement to remove- Return type:
- Returns:
A list of positions of statements that have been deleted
- Raises:
ValueError – If the position is out of bounds for this test case
- abstract set_statement(statement, position)[source]
Set new statement at position.
- Parameters:
statement (
Statement) – the new statementposition (
int) – the position for the new statement
- Returns:
DAR202
- Return type:
A variable reference to the statements return value, if any # noqa
- abstract size()[source]
Provides the number of statements in the test case.
- Returns:
DAR202
- Return type:
The number of statements in the test case # noqa
pynguin.testcase.defaulttestcase
Provides a default implementation of a test case.
- class pynguin.testcase.defaulttestcase.DefaultTestCase(test_cluster)[source]
A default implementation of a test case.
- accept(visitor)[source]
Handles a test visitor.
- Parameters:
visitor (
TestCaseVisitor) – The test visitor to accept- Return type:
- add_statement(statement, position=-1)[source]
Adds a new statement to the test case.
The optional position parameter specifies the position. If it is not given, the statement will be added to the end of the test case.
- Parameters:
statement (
Statement) – The new statementposition (
int) – The optional position where to put the statement
- Return type:
VariableReference|None
- Returns: # noqa: DAR202
The return value of the statement. Notice that the test might choose to modify the statement you inserted. You should use the returned variable reference and not use references. Can be None, if this statement does not create a variable.
- add_variable_creating_statement(statement, position=-1)[source]
Overloaded version of add_statement that adds a statement.
- Parameters:
statement (
VariableCreatingStatement) – The new statementposition (
int) – The optional position where to put the statement
- Return type:
VariableReference
- Returns: # noqa: DAR202
The return value of the statement. Notice that the test might choose to modify the statement you inserted. You should use the returned variable reference and not use references.
- contains(statement)[source]
Determines whether or not the test case contains a specific statement.
- Parameters:
statement (
Statement) – The statement to search in the test case- Returns:
DAR202
- Return type:
Whether or not the test case contains the statement # noqa
- get_assertions()[source]
Get all assertions that exist for this test case.
- Return type:
list[Assertion]
- get_dependencies(var)[source]
Provides all variables on which var depends.
- Parameters:
var (
VariableReference) – the variable whose dependencies we are looking for.- Returns:
DAR202
- Return type:
a set of variables on which var depends on. # noqa
- get_forward_dependencies(var)[source]
Provides all variables that depend on var.
- Parameters:
var (
VariableReference) – the variable for which we look for all dependent statements of- Returns:
DAR202
- Return type:
a set of variables that depend on var. # noqa
- get_statement(position)[source]
Provides access to a statement at a given position.
- Parameters:
position (
int) – The position of the statement in the test case- Returns:
DAR202
- Return type:
The statement at the position # noqa
- has_statement(position)[source]
Check if there is a statement at the given position.
- Parameters:
position (
int) – The index of the statement- Returns:
DAR202
- Return type:
Whether or not there is a statement at the given position # noqa
- remove_statement(statement)[source]
Remove the given statement from this test case.
- Parameters:
statement (
Statement) – The statement to remove.- Return type:
- remove_statement_with_forward_dependencies(statement)[source]
Removes the given statement along with all its forward dependencies.
- Parameters:
statement (
Statement) – The statement to remove- Return type:
- Returns:
A list of positions of statements that have been deleted
- Raises:
ValueError – If the statement is not contained in the test case
- remove_with_forward_dependencies(position)[source]
Removes a statement at the given position along with all its forward dependencies.
- Parameters:
position (
int) – The position of the statement to remove- Return type:
- Returns:
A list of positions of statements that have been deleted
- Raises:
ValueError – If the position is out of bounds for this test case
- set_statement(statement, position)[source]
Set new statement at position.
- Parameters:
statement (
Statement) – the new statementposition (
int) – the position for the new statement
- Returns:
DAR202
- Return type:
A variable reference to the statements return value, if any # noqa
pynguin.ga.testcasefactory
Provides a factories for generating different kind of test cases.
- class pynguin.ga.testcasefactory.RandomLengthTestCaseFactory(test_factory, test_cluster)[source]
Create random test cases with random length.
- class pynguin.ga.testcasefactory.SeededTestCaseFactory(delegate, population_provider)[source]
Factory for getting seeded test cases.
With a certain probability a seeded testcase is returned instead of a randomly generated one. If a seeded testcase is returned, it is taken randomly from the pool of seeded testcases. If a randomly generated testcase is returned, the generation is delegated to the RandomLengthTestCaseFactory.
pynguin.testcase.execution
Contains all code related to test-case execution.
- class pynguin.testcase.execution.AbstractTestCaseExecutor[source]
Interface for a test case executor.
- abstract add_observer(observer)[source]
Add an execution observer.
- Parameters:
observer (
ExecutionObserver) – the observer to be added.- Return type:
- abstract add_remote_observer(remote_observer)[source]
Add a remote execution observer.
- Parameters:
remote_observer (
RemoteExecutionObserver) – the remote observer to be added.- Return type:
- abstract execute(test_case)[source]
Executes all statements of the given test case.
- Parameters:
test_case (
TestCase) – the test case that should be executed.- Raises:
RuntimeError – If something goes wrong inside Pynguin during execution.
- Return type:
- Returns:
Result of the execution
- execute_multiple(test_cases)[source]
Executes multiple test cases.
- Parameters:
test_cases (
Iterable[TestCase]) – The test cases that should be executed.- Raises:
RuntimeError – If something goes wrong inside Pynguin during execution.
- Yields:
The results of the execution
- Return type:
- abstract property module_provider: ModuleProvider
The module provider used by this executor.
- Returns:
The used module provider
- abstract property subject_properties: SubjectProperties
Provide access to the subject properties.
- Returns:
The subject properties
- abstract temporarily_add_observer(observer)[source]
Temporarily add the given observer.
- Parameters:
observer (
ExecutionObserver) – The observer to add.- Return type:
- abstract temporarily_add_remote_observer(remote_observer)[source]
Temporarily add a remote observer.
- Parameters:
remote_observer (
RemoteExecutionObserver) – The remote observer to add.- Return type:
- class pynguin.testcase.execution.ExecutionContext(module_provider)[source]
Contains information required in the context of an execution.
The context contains, e.g., the used variables, modules, and the AST representation of the statements that should be executed.
- get_reference_value(reference)[source]
Resolve the given reference in this execution context.
- Parameters:
reference (
Reference) – The reference to resolve.- Raises:
ValueError – If the root of the reference can not be resolved.
- Return type:
- Returns:
The value that is resolved.
- property global_namespace: dict[str, ModuleType]
The global namespace.
- Returns:
The global namespace
- property module_aliases: NamingScope
The module aliases.
- Returns:
A naming scope that maps the used modules to their alias.
- node_for_assertion(assertion, statement_node)[source]
Transforms the given assertion in an executable ast node.
- Parameters:
assertion (
Assertion) – The assertion that should be converted.statement_node (
stmt) – The ast node of the statement for the assertion.
- Return type:
stmt- Returns:
An ast node.
- node_for_statement(statement)[source]
Transforms the given statement in an executable ast node.
- Parameters:
statement (
Statement) – The statement that should be converted.- Return type:
stmt- Returns:
An ast node.
- replace_variable_value(variable, new_value)[source]
Replace the value of the variable with the new value.
- property variable_names: NamingScope
The variable names.
- Returns:
A naming scope that maps the used variables to their names.
- class pynguin.testcase.execution.ExecutionObserver[source]
An observer that can be used to observe the execution of a test case.
- abstract after_remote_test_case_execution(test_case, result)[source]
Called after test case execution from the main thread.
Note: This method is always called, though the data you expect in the execution might not be there, if the execution of the test case timed out. You are not allowed to access thread local state here (due to how threading.local works, it isn’t even possible ;)), but you can do some postprocessing with the data from the execution result here.
- Parameters:
test_case (
TestCase) – The test cases that was executedresult (
ExecutionResult) – The execution result
- Return type:
- abstract before_remote_test_case_execution(test_case)[source]
Called before test case execution from the main thread.
Note: This method can be called with several test cases before the after_remote_test_case_execution method is called.
- abstract property remote_observer: RemoteExecutionObserver
The remote observer.
- Returns:
The remote observer
- class pynguin.testcase.execution.ExecutionResult(timeout=False)[source]
Result of an execution.
- delete_statement_data(deleted_statements)[source]
Delete statements at given indices.
It may happen that the test case is modified after execution, for example, by removing unused primitives. We have to update the execution result to reflect this, otherwise the indexes maybe wrong.
- get_first_position_of_thrown_exception()[source]
Provide the index of the first thrown exception or None.
- has_test_exceptions()[source]
Returns true if any exceptions were thrown during the execution.
- Return type:
- Returns:
Whether the test has exceptions
- report_new_thrown_exception(stmt_idx, ex)[source]
Report an exception that was thrown during execution.
- Parameters:
stmt_idx (
int) – the index of the statement, that caused the exceptionex (
BaseException) – the exception
- Return type:
- class pynguin.testcase.execution.ModuleProvider[source]
Class for providing modules.
- add_mutated_version(module_name, mutated_module)[source]
Adds a mutated version of a module to the collection of mutated modules.
- Parameters:
module_name (
str) – for the module name of the module, which should be mutated.mutated_module (
ModuleType) – the custom module, which should be used.
- Return type:
- get_module(module_name)[source]
Provides a module.
Either from sys.modules or if a mutated version for the given module name exists then the mutated version of the module will be returned.
- Parameters:
module_name (
str) – string for the module alias, which should be loaded- Raises:
ModuleNotImportedError – If the module is not imported.
- Return type:
- Returns:
the module which should be loaded.
- class pynguin.testcase.execution.OutputSuppressionContext[source]
A context manager that suppresses stdout and stderr.
Operates at two levels: - Python level: redirects
sys.stdout/sys.stderrto/dev/null. - OS level: saves file descriptors 0/1/2 viaos.dupso that if the SUTcloses them (e.g.
with open(1, 'w')where the int happens to be a stdio fd), they are restored on exit.
- class pynguin.testcase.execution.PatchRandomOnUnpickle[source]
A hook that patches random when unpickled in a subprocess.
This ensures that random.Random.seed is patched before the SUT is unpickled and potentially creates new random.Random instances (e.g., mimesis).
- class pynguin.testcase.execution.RemoteAssertionExecutionObserver[source]
A remote observer which executes the assertions of statements.
Enables slicing on the recorded data.
- after_statement_execution(statement, executor, exec_ctx, exception)[source]
Called after a statement was executed.
- Parameters:
statement (
Statement) – the statement that was executed.executor (
TestCaseExecutor) – the executor, in case you want to execute something.exec_ctx (
ExecutionContext) – the current execution context.exception (
BaseException|None) – the exception that was thrown, if any.
- Return type:
- after_test_case_execution(executor, test_case, result)[source]
Not used.
- Parameters:
executor (
TestCaseExecutor) – Not usedtest_case (
TestCase) – Not usedresult (
ExecutionResult) – Not used
- Return type:
- before_statement_execution(statement, node, exec_ctx)[source]
Called before a statement is executed.
- Parameters:
statement (
Statement) – the statement about to be executed.node (
stmt) – the ast node representing the statement.exec_ctx (
ExecutionContext) – the current execution context.
- Return type:
stmt- Returns:
An ast node. You may choose to modify this node to change what is executed.
- class pynguin.testcase.execution.RemoteExecutionObserver[source]
A remote observer that can be used to observe the execution of a test case.
Important Note: If an observer is stateful, then this state must be encapsulated in a threading.local, i.e., be bound to a thread. Note that thread local data is initialized per thread, so there is no need to clear any pre-existing data (because there is none), as every thread gets its own instance.
Methods in this class are not allowed to interact with the ‘outside’ because this class could be sent to a remote environment. The only thing that should leave an observer are results when they are written to the execution result in RemoteExecutionObserver::after_test_case_execution.
You may interact with the ‘outside’ in ExecutionObserver::after_remote_test_case_execution.
Note: Usage of threading.local may interfere with debugging tools, such as pydevd. In such a case, disable Cython by setting the following environment variable: PYDEVD_USE_CYTHON=NO
For more details, look at some implementations, e.g., AssertionTraceObserver.
- abstract after_statement_execution(statement, executor, exec_ctx, exception)[source]
Called after a statement was executed.
- Parameters:
statement (
Statement) – the statement that was executed.executor (
TestCaseExecutor) – the executor, in case you want to execute something.exec_ctx (
ExecutionContext) – the current execution context.exception (
BaseException|None) – the exception that was thrown, if any.
- Return type:
- abstract after_test_case_execution(executor, test_case, result)[source]
Called after test case execution.
The call happens from the remote environment that executed the test case. You should override this method to extract information from the thread local storage to the execution result.
Note: When a timeout occurs, then this method might not be called at all.
- Parameters:
executor (
TestCaseExecutor) – The executor that executed the test casetest_case (
TestCase) – The test cases that was executedresult (
ExecutionResult) – The execution result
- Return type:
- abstract before_statement_execution(statement, node, exec_ctx)[source]
Called before a statement is executed.
- Parameters:
statement (
Statement) – the statement about to be executed.node (
stmt) – the ast node representing the statement.exec_ctx (
ExecutionContext) – the current execution context.
- Return type:
stmt- Returns:
An ast node. You may choose to modify this node to change what is executed.
- class pynguin.testcase.execution.RemoteReturnTypeObserver[source]
An observer which observes the runtime types seen during execution.
- after_statement_execution(statement, executor, exec_ctx, exception)[source]
Called after a statement was executed.
- Parameters:
statement (
Statement) – the statement that was executed.executor (
TestCaseExecutor) – the executor, in case you want to execute something.exec_ctx (
ExecutionContext) – the current execution context.exception (
BaseException|None) – the exception that was thrown, if any.
- Return type:
- after_test_case_execution(executor, test_case, result)[source]
Called after test case execution.
The call happens from the remote environment that executed the test case. You should override this method to extract information from the thread local storage to the execution result.
Note: When a timeout occurs, then this method might not be called at all.
- Parameters:
executor (
TestCaseExecutor) – The executor that executed the test casetest_case (
TestCase) – The test cases that was executedresult (
ExecutionResult) – The execution result
- before_statement_execution(statement, node, exec_ctx)[source]
Called before a statement is executed.
- Parameters:
statement (
Statement) – the statement about to be executed.node (
stmt) – the ast node representing the statement.exec_ctx (
ExecutionContext) – the current execution context.
- Return type:
stmt- Returns:
An ast node. You may choose to modify this node to change what is executed.
- class pynguin.testcase.execution.RemoteTypeTracingObserver[source]
A remote execution observer used for type tracing.
- after_statement_execution(statement, executor, exec_ctx, exception=None)[source]
Called after a statement was executed.
- Parameters:
statement (
Statement) – the statement that was executed.executor (
TestCaseExecutor) – the executor, in case you want to execute something.exec_ctx (
ExecutionContext) – the current execution context.exception (
Optional[BaseException]) – the exception that was thrown, if any.
- Return type:
- after_test_case_execution(executor, test_case, result)[source]
Called after test case execution.
The call happens from the remote environment that executed the test case. You should override this method to extract information from the thread local storage to the execution result.
Note: When a timeout occurs, then this method might not be called at all.
- Parameters:
executor (
TestCaseExecutor) – The executor that executed the test casetest_case (
TestCase) – The test cases that was executedresult (
ExecutionResult) – The execution result
- Return type:
- before_statement_execution(statement, node, exec_ctx)[source]
Called before a statement is executed.
- Parameters:
statement (
Statement) – the statement about to be executed.node (
stmt) – the ast node representing the statement.exec_ctx (
ExecutionContext) – the current execution context.
- Return type:
stmt- Returns:
An ast node. You may choose to modify this node to change what is executed.
- class pynguin.testcase.execution.ReturnTypeObserver(test_cluster)[source]
Observes the runtime types seen during execution.
Updates the return types of the called function with the observed types.
- after_remote_test_case_execution(test_case, result)[source]
Called after test case execution from the main thread.
Note: This method is always called, though the data you expect in the execution might not be there, if the execution of the test case timed out. You are not allowed to access thread local state here (due to how threading.local works, it isn’t even possible ;)), but you can do some postprocessing with the data from the execution result here.
- Parameters:
test_case (
TestCase) – The test cases that was executedresult (
ExecutionResult) – The execution result
- property remote_observer: RemoteExecutionObserver
The remote observer.
- Returns:
The remote observer
- class pynguin.testcase.execution.SubprocessTestCaseExecutor(subject_properties, module_provider=None, maximum_test_execution_timeout=5, test_execution_time_per_statement=1)[source]
An executor that executes the generated test cases in a subprocess.
- class SubprocessResultContext(test_cases_tuple, references_bindings, process, receiving_connection, connection_status, remote_observers)[source]
Context for processing subprocess results.
- execute(test_case)[source]
Executes all statements of the given test case.
- Parameters:
test_case (
TestCase) – the test case that should be executed.- Raises:
RuntimeError – If something goes wrong inside Pynguin during execution.
- Return type:
- Returns:
Result of the execution
- execute_multiple(test_cases)[source]
Executes multiple test cases.
- Parameters:
test_cases (
Iterable[TestCase]) – The test cases that should be executed.- Raises:
RuntimeError – If something goes wrong inside Pynguin during execution.
- Yields:
The results of the execution
- Return type:
- class pynguin.testcase.execution.TestCaseExecutor(subject_properties, module_provider=None, maximum_test_execution_timeout=5, test_execution_time_per_statement=1)[source]
An executor that executes the generated test cases.
- add_observer(observer)[source]
Add an execution observer.
- Parameters:
observer (
ExecutionObserver) – the observer to be added.- Return type:
- add_remote_observer(remote_observer)[source]
Add a remote execution observer.
- Parameters:
remote_observer (
RemoteExecutionObserver) – the remote observer to be added.- Return type:
- execute(test_case)[source]
Executes all statements of the given test case.
- Parameters:
test_case (
TestCase) – the test case that should be executed.- Raises:
RuntimeError – If something goes wrong inside Pynguin during execution.
- Return type:
- Returns:
Result of the execution
- execute_ast(ast_node, exec_ctx)[source]
Execute the given ast_node in the given context.
You can use this in an observer if you also need to execute an AST Node.
- Parameters:
ast_node (
Module) – The node to execute.exec_ctx (
ExecutionContext) – The execution context
- Return type:
- Returns:
The raised exception, if any.
- property module_provider: ModuleProvider
The module provider used by this executor.
- Returns:
The used module provider
- property subject_properties: SubjectProperties
Provide access to the subject properties.
- Returns:
The subject properties
- temporarily_add_observer(observer)[source]
Temporarily add the given observer.
- Parameters:
observer (
ExecutionObserver) – The observer to add.- Return type:
- class pynguin.testcase.execution.TypeTracingObserver(cluster)[source]
An execution observer used for type tracing.
It wraps parameters in proxies in order to make better guesses on their type.
- after_remote_test_case_execution(test_case, result)[source]
Called after test case execution from the main thread.
Note: This method is always called, though the data you expect in the execution might not be there, if the execution of the test case timed out. You are not allowed to access thread local state here (due to how threading.local works, it isn’t even possible ;)), but you can do some postprocessing with the data from the execution result here.
- Parameters:
test_case (
TestCase) – The test cases that was executedresult (
ExecutionResult) – The execution result
- Return type:
- property remote_observer: RemoteTypeTracingObserver
The remote observer.
- Returns:
The remote observer
- class pynguin.testcase.execution.TypeTracingTestCaseExecutor(delegate, cluster, type_tracing_probability=1.0)[source]
A test case executor that delegates to another executor.
Every test case is executed twice, one time for the regular result and one time with proxies in order to refine parameter types.
- add_observer(observer)[source]
Add an execution observer.
- Parameters:
observer (
ExecutionObserver) – the observer to be added.- Return type:
- add_remote_observer(remote_observer)[source]
Add a remote execution observer.
- Parameters:
remote_observer (
RemoteExecutionObserver) – the remote observer to be added.- Return type:
- execute(test_case)[source]
Executes all statements of the given test case.
- Parameters:
test_case (
TestCase) – the test case that should be executed.- Raises:
RuntimeError – If something goes wrong inside Pynguin during execution.
- Return type:
- Returns:
Result of the execution
- property module_provider: ModuleProvider
The module provider used by this executor.
- Returns:
The used module provider
- property subject_properties: SubjectProperties
Provide access to the subject properties.
- Returns:
The subject properties
- temporarily_add_observer(observer)[source]
Temporarily add the given observer.
- Parameters:
observer (
ExecutionObserver) – The observer to add.- Return type:
- temporarily_add_remote_observer(remote_observer)[source]
Temporarily add a remote observer.
- Parameters:
remote_observer (
RemoteExecutionObserver) – The remote observer to add.- Return type:
pynguin.instrumentation.tracer
Contains all code related to test-case execution.
- class pynguin.instrumentation.tracer.AbstractExecutionTracer[source]
An abstract execution tracer.
The results are stored in an execution trace.
- abstract check()[source]
Check if the thread that called this method should still be running.
- Raises:
RuntimeError – if the thread is not running anymore.
- Return type:
- abstract executed_bool_predicate(value, predicate)[source]
A predicate that is based on a boolean value was executed.
- Parameters:
value – the value
predicate (
int) – the predicate identifier
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract executed_code_object(code_object_id)[source]
Mark a code object as executed.
This means, that the routine which refers to this code object was at least called once.
- Parameters:
code_object_id (
int) – the code object id to mark- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract executed_compare_predicate(value1, value2, predicate, cmp_op)[source]
A predicate that is based on a comparison was executed.
- Parameters:
value1 – the first value
value2 – the second value
predicate (
int) – the predicate identifiercmp_op (
PynguinCompare) – the compare operation
- Raises:
RuntimeError – raised when called from another thread.
AssertionError – when encountering an unknown compare op.
- Return type:
- abstract executed_exception_match(err, exc, predicate)[source]
A predicate that is based on exception matching was executed.
- Parameters:
err (
BaseException|type[BaseException]) – The raised exceptionexc (
type[BaseException]) – The matching conditionpredicate (
int) – the predicate identifier
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract executed_in_presence_predicate(value1, value2, predicate)[source]
An auxiliary membership predicate was executed.
Computes a guided branch distance for
value1 in value2with an execution-time guard on the container size to limit overhead.- Parameters:
value1 – The prospective key/index to check membership for.
value2 – The container to check membership in.
predicate (
int) – The predicate identifier.
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract get_trace()[source]
Get the trace with the current information.
- Return type:
- Returns:
The current execution trace
- abstract property import_trace: ExecutionTrace
The trace that was generated when the SUT was imported.
- Returns:
The execution trace after executing the import statements
- abstract init_trace()[source]
Create a new trace that only contains the trace data from the import.
- Return type:
- abstract is_disabled()[source]
Should we track anything?
We might have to disable tracing, e.g. when calling __eq__ ourselves. Otherwise, we create an endless recursion.
- Return type:
- Returns:
Whether we should track anything
- abstract reset()[source]
Resets everything.
Should be called before instrumentation. Clears all data, so we can handle a reload of the SUT.
- Return type:
- abstract stop()[source]
Stop the tracer.
This should be called when the tracer is no longer needed, e.g., when the test case execution is finished.
- Return type:
- abstract store_import_trace()[source]
Stores the current trace as the import trace.
Should only be done once, after a module was loaded. The import trace will be merged into every subsequently recorded trace.
- Return type:
- temporarily_disable()[source]
Temporarily disable tracing.
If the tracing is already disabled, do nothing.
- temporarily_enable()[source]
Temporarily enable tracing.
If the tracing is already enabled, do nothing.
- abstract track_assertion_position(assertion)[source]
Track the position of an assertion in the trace.
- Parameters:
assertion (
Assertion) – the assertion of the statement- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract track_attribute_access(module, code_object_id, node_id, opcode, lineno, offset, attr_name, obj)[source]
Track an attribute access instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionobj (
object) – the object containing the accessed attribute
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract track_call(module, code_object_id, node_id, opcode, lineno, offset, arg)[source]
Track a method call instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionarg (
int) – the argument used in the method call
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract track_exception_assertion(statement)[source]
Track the position of an exception assertion in the trace.
Normally, to track an assertion, we trace the POP_JUMP_IF_TRUE instruction contained by each assertion. The pytest exception assertion does not use an assertion containing this instruction. Therefore, we trace the instruction that was last executed before the exception.
- Parameters:
statement (
Statement) – the statement causing the exception- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract track_generic(module, code_object_id, node_id, opcode, lineno, offset)[source]
Track a generic instruction inside the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract track_jump(module, code_object_id, node_id, opcode, lineno, offset, target_id)[source]
Track a jump instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructiontarget_id (
int) – the offset of the target of the jump
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract track_line_visit(line_id)[source]
Tracks the visit of a line.
- Parameters:
line_id (
int) – the if of the line that was visited- Raises:
RuntimeError – raised when called from another thread
- Return type:
- abstract track_memory_access(module, code_object_id, node_id, opcode, lineno, offset, var_name, var_value)[source]
Track a memory access instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionvar_name (
str|CellVar|FreeVar|tuple[str|CellVar|FreeVar,str|CellVar|FreeVar]) – the used variable namevar_value (
object) – the value stored in the used variable
- Raises:
ValueError – when no argument is given
RuntimeError – raised when called from another thread
- Return type:
- abstract track_return(module, code_object_id, node_id, opcode, lineno, offset)[source]
Track a return instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- class pynguin.instrumentation.tracer.CodeObjectMetaData(code_object, parent_code_object_id, cfg, cdg)[source]
Stores meta data of a code object.
- class pynguin.instrumentation.tracer.ExecutedAssertion(trace_position, assertion)[source]
Data class for assertions of a testcase traced during execution for slicing.
- class pynguin.instrumentation.tracer.ExecutionTrace(executed_code_objects=<factory>, executed_predicates=<factory>, true_distances=<factory>, false_distances=<factory>, covered_line_ids=<factory>, executed_instructions=<factory>, object_addresses=<factory>, executed_assertions=<factory>, checked_lines=<factory>)[source]
Stores trace information about the execution.
- add_attribute_instruction(module, code_object_id, node_id, opcode, lineno, offset, attr_name, src_address, arg_address, is_mutable_type, is_method)[source]
Creates a new ExecutedAttributeInstruction object and adds it to the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionattr_name (
str) – the name of the accessed attributesrc_address (
int) – the memory address of the attributearg_address (
int) – the memory address of the argumentis_mutable_type (
bool) – if the attribute is mutableis_method (
bool) – if the attribute is a method
- Return type:
- add_call_instruction(module, code_object_id, node_id, opcode, lineno, offset, arg)[source]
Creates a new ExecutedCallInstruction object and adds it to the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionarg (
int) – the argument to the instruction
- Return type:
- add_instruction(module, code_object_id, node_id, opcode, lineno, offset)[source]
Creates a new ExecutedInstruction object and adds it to the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Return type:
- add_jump_instruction(module, code_object_id, node_id, opcode, lineno, offset, target_id)[source]
Creates a new ExecutedControlInstruction object and adds it to the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructiontarget_id (
int) – the target offset to jump to
- Return type:
- add_memory_instruction(module, code_object_id, node_id, opcode, lineno, offset, arg_name, arg_address, is_mutable_type, object_creation)[source]
Creates a new ExecutedMemoryInstruction object and adds it to the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionarg_address (
int|tuple[int,int]) – the memory address of the argumentis_mutable_type (
bool|tuple[bool,bool]) – if the argument is mutableobject_creation (
bool|tuple[bool,bool]) – if the instruction creates the object used
- Return type:
- add_return_instruction(module, code_object_id, node_id, opcode, lineno, offset)[source]
Creates a new ExecutedReturnInstruction object and adds it to the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Return type:
- merge(other)[source]
Merge the values from the other execution trace.
- Parameters:
other (
ExecutionTrace) – Merges the other traces into this trace- Return type:
- class pynguin.instrumentation.tracer.ExecutionTracer[source]
Tracks branch distances and covered statements during execution.
The results are stored in an execution trace.
- static attribute_lookup(object_type, attribute)[source]
Check the dictionary of classes making up the MRO (method resolution order).
It is inspired by the _PyType_Lookup C function in CPython.
- check()[source]
Check if the thread that called this method should still be running.
- Raises:
RuntimeError – if the thread is not running anymore.
- Return type:
- executed_bool_predicate(value, predicate)[source]
A predicate that is based on a boolean value was executed.
- Parameters:
value – the value
predicate (
int) – the predicate identifier
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- executed_code_object(code_object_id)[source]
Mark a code object as executed.
This means, that the routine which refers to this code object was at least called once.
- Parameters:
code_object_id (
int) – the code object id to mark- Raises:
RuntimeError – raised when called from another thread
- Return type:
- executed_compare_predicate(value1, value2, predicate, cmp_op)[source]
A predicate that is based on a comparison was executed.
- Parameters:
value1 – the first value
value2 – the second value
predicate (
int) – the predicate identifiercmp_op (
PynguinCompare) – the compare operation
- Raises:
RuntimeError – raised when called from another thread.
AssertionError – when encountering an unknown compare op.
- Return type:
- executed_exception_match(err, exc, predicate)[source]
A predicate that is based on exception matching was executed.
- Parameters:
err (
BaseException|type[BaseException]) – The raised exceptionexc (
type[BaseException]) – The matching conditionpredicate (
int) – the predicate identifier
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- executed_in_presence_predicate(value1, value2, predicate)[source]
Conditionally compute an auxiliary ‘IN’ predicate distance.
This helper provides guidance for subscripts like
container[key]by reporting a membership distancekey in containerbefore the subscript executes. To control overhead, it only computes a distance when the container is sized and its size does not exceedmax_container_size.
- get_trace()[source]
Get the trace with the current information.
- Return type:
- Returns:
The current execution trace
- property import_trace: ExecutionTrace
The trace that was generated when the SUT was imported.
- Returns:
The execution trace after executing the import statements
- init_trace()[source]
Create a new trace that only contains the trace data from the import.
- Return type:
- is_disabled()[source]
Should we track anything?
We might have to disable tracing, e.g. when calling __eq__ ourselves. Otherwise, we create an endless recursion.
- Return type:
- Returns:
Whether we should track anything
- reset()[source]
Resets everything.
Should be called before instrumentation. Clears all data, so we can handle a reload of the SUT.
- Return type:
- stop()[source]
Stop the tracer.
This should be called when the tracer is no longer needed, e.g., when the test case execution is finished.
- Return type:
- store_import_trace()[source]
Stores the current trace as the import trace.
Should only be done once, after a module was loaded. The import trace will be merged into every subsequently recorded trace.
- Return type:
- track_assertion_position(assertion)[source]
Track the position of an assertion in the trace.
- Parameters:
assertion (
Assertion) – the assertion of the statement- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_attribute_access(module, code_object_id, node_id, opcode, lineno, offset, attr_name, obj)[source]
Track an attribute access instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionobj (
object) – the object containing the accessed attribute
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_call(module, code_object_id, node_id, opcode, lineno, offset, arg)[source]
Track a method call instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionarg (
int) – the argument used in the method call
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_exception_assertion(statement)[source]
Track the position of an exception assertion in the trace.
Normally, to track an assertion, we trace the POP_JUMP_IF_TRUE instruction contained by each assertion. The pytest exception assertion does not use an assertion containing this instruction. Therefore, we trace the instruction that was last executed before the exception.
- Parameters:
statement (
Statement) – the statement causing the exception- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_generic(module, code_object_id, node_id, opcode, lineno, offset)[source]
Track a generic instruction inside the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_jump(module, code_object_id, node_id, opcode, lineno, offset, target_id)[source]
Track a jump instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructiontarget_id (
int) – the offset of the target of the jump
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_line_visit(line_id)[source]
Tracks the visit of a line.
- Parameters:
line_id (
int) – the if of the line that was visited- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_memory_access(module, code_object_id, node_id, opcode, lineno, offset, var_name, var_value)[source]
Track a memory access instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionvar_name (
str|CellVar|FreeVar|tuple[str|CellVar|FreeVar,str|CellVar|FreeVar]) – the used variable namevar_value (
object) – the value stored in the used variable
- Raises:
ValueError – when no argument is given
RuntimeError – raised when called from another thread
- Return type:
- track_return(module, code_object_id, node_id, opcode, lineno, offset)[source]
Track a return instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- class pynguin.instrumentation.tracer.InstrumentationExecutionTracer(tracer)[source]
An InstrumentationExecutionTracer is a sort of proxy for an ExecutionTracer.
This was done because when a module is instrumented, instructions are inserted into its bytecode and refer directly to a tracer. This means that without the use of a proxy, it would be impossible to modify the tracer, as there are direct references between the bytecode instructions and the tracer. By adding a proxy between the bytecode and the tracer, this ensures that the bytecode only has direct references to the proxy but no references to the tracer, so the tracer can be modified without any problems.
- check()[source]
Check if the thread that called this method should still be running.
- Raises:
RuntimeError – if the thread is not running anymore.
- Return type:
- executed_bool_predicate(value, predicate)[source]
A predicate that is based on a boolean value was executed.
- Parameters:
value – the value
predicate (
int) – the predicate identifier
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- executed_code_object(code_object_id)[source]
Mark a code object as executed.
This means, that the routine which refers to this code object was at least called once.
- Parameters:
code_object_id (
int) – the code object id to mark- Raises:
RuntimeError – raised when called from another thread
- Return type:
- executed_compare_predicate(value1, value2, predicate, cmp_op)[source]
A predicate that is based on a comparison was executed.
- Parameters:
value1 – the first value
value2 – the second value
predicate (
int) – the predicate identifiercmp_op (
PynguinCompare) – the compare operation
- Raises:
RuntimeError – raised when called from another thread.
AssertionError – when encountering an unknown compare op.
- Return type:
- executed_exception_match(err, exc, predicate)[source]
A predicate that is based on exception matching was executed.
- Parameters:
err (
BaseException|type[BaseException]) – The raised exceptionexc (
type[BaseException]) – The matching conditionpredicate (
int) – the predicate identifier
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- executed_in_presence_predicate(value1, value2, predicate)[source]
An auxiliary membership predicate was executed.
Computes a guided branch distance for
value1 in value2with an execution-time guard on the container size to limit overhead.- Parameters:
value1 – The prospective key/index to check membership for.
value2 – The container to check membership in.
predicate (
int) – The predicate identifier.
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- get_trace()[source]
Get the trace with the current information.
- Return type:
- Returns:
The current execution trace
- property import_trace: ExecutionTrace
The trace that was generated when the SUT was imported.
- Returns:
The execution trace after executing the import statements
- init_trace()[source]
Create a new trace that only contains the trace data from the import.
- Return type:
- is_disabled()[source]
Should we track anything?
We might have to disable tracing, e.g. when calling __eq__ ourselves. Otherwise, we create an endless recursion.
- Return type:
- Returns:
Whether we should track anything
- reset()[source]
Resets everything.
Should be called before instrumentation. Clears all data, so we can handle a reload of the SUT.
- Return type:
- stop()[source]
Stop the tracer.
This should be called when the tracer is no longer needed, e.g., when the test case execution is finished.
- Return type:
- store_import_trace()[source]
Stores the current trace as the import trace.
Should only be done once, after a module was loaded. The import trace will be merged into every subsequently recorded trace.
- Return type:
- track_assertion_position(assertion)[source]
Track the position of an assertion in the trace.
- Parameters:
assertion (
Assertion) – the assertion of the statement- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_attribute_access(module, code_object_id, node_id, opcode, lineno, offset, attr_name, obj)[source]
Track an attribute access instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionobj (
object) – the object containing the accessed attribute
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_call(module, code_object_id, node_id, opcode, lineno, offset, arg)[source]
Track a method call instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionarg (
int) – the argument used in the method call
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_exception_assertion(statement)[source]
Track the position of an exception assertion in the trace.
Normally, to track an assertion, we trace the POP_JUMP_IF_TRUE instruction contained by each assertion. The pytest exception assertion does not use an assertion containing this instruction. Therefore, we trace the instruction that was last executed before the exception.
- Parameters:
statement (
Statement) – the statement causing the exception- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_generic(module, code_object_id, node_id, opcode, lineno, offset)[source]
Track a generic instruction inside the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_jump(module, code_object_id, node_id, opcode, lineno, offset, target_id)[source]
Track a jump instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructiontarget_id (
int) – the offset of the target of the jump
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_line_visit(line_id)[source]
Tracks the visit of a line.
- Parameters:
line_id (
int) – the if of the line that was visited- Raises:
RuntimeError – raised when called from another thread
- Return type:
- track_memory_access(module, code_object_id, node_id, opcode, lineno, offset, var_name, var_value)[source]
Track a memory access instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instructionvar_name (
str|CellVar|FreeVar|tuple[str|CellVar|FreeVar,str|CellVar|FreeVar]) – the used variable namevar_value (
object) – the value stored in the used variable
- Raises:
ValueError – when no argument is given
RuntimeError – raised when called from another thread
- Return type:
- track_return(module, code_object_id, node_id, opcode, lineno, offset)[source]
Track a return instruction in the trace.
- Parameters:
module (
str) – File name of the module containing the instructioncode_object_id (
int) – code object containing the instructionnode_id (
int) – the node of the code object containing the instructionopcode (
int) – the opcode of the instructionlineno (
int) – the line number of the instructionoffset (
int) – the offset of the instruction
- Raises:
RuntimeError – raised when called from another thread
- Return type:
- class pynguin.instrumentation.tracer.LineMetaData(code_object_id, file_name, line_number)[source]
Stores meta data of a line.
- class pynguin.instrumentation.tracer.PredicateMetaData(line_no, code_object_id, node)[source]
Stores meta data of a predicate.
- class pynguin.instrumentation.tracer.SubjectProperties(instrumentation_tracer=<factory>, code_object_counter=<factory>, existing_code_objects=<factory>, existing_predicates=<factory>, existing_lines=<factory>)[source]
Contains properties about the subject under test.
The subject properties are code objects, predicates and lines:
Code Objects: Compiled chunks of code (functions, methods, modules). Tracked in CodeObjectMetaData with references to the compiled code, parent, control graphs, and a unique ID. Represent the program’s structural units.
Predicates: Decision points within code objects (e.g.,
if,while). Tracked in PredicateMetaData with line number, owning code object, and graph node. Used for branch coverage and measuring branch distances.Lines: Individual lines of code within code objects. Tracked in LineMetaData with file name and line number. Used for measuring line coverage.
Example:
def example(x): if x > 0: # Predicate return "pos" return "non-pos" # The function ``example`` is a Code Object and ``x > 0`` is a Predicate.
- property branch_less_code_objects: Iterable[int]
Get the existing code objects that do not contain a branch.
Every code object is initially seen as branch-less until a predicate is registered for it.
- Returns:
The existing code objects that do not contain a branch.
- create_code_object_id()[source]
Create a new code object ID.
- Return type:
- Returns:
A new code object ID.
- register_code_object(code_object_id, meta)[source]
Declare that a code object exists.
- Parameters:
code_object_id (
int) – the id of the code object, which should be used to identify the objectinstrumentation. (during)
meta (
CodeObjectMetaData) – the code objects existing
- Return type:
- register_line(meta)[source]
Tracks the existence of a line.
- Parameters:
meta (
LineMetaData) – Metadata about the line- Return type:
- Returns:
the id of the registered line
- register_predicate(meta)[source]
Declare that a predicate exists.
- Parameters:
meta (
PredicateMetaData) – Metadata about the predicates- Return type:
- Returns:
the id of the predicate, which can be used to identify the predicate during instrumentation.
- validate_execution_trace(execution_trace)[source]
Validate the execution trace.
- Parameters:
execution_trace (
ExecutionTrace) – The execution trace to validate- Raises:
AssertionError – if the execution trace is invalid
- Return type:
pynguin.ga.computations
Provides classes for computations on chromosomes, e.g., fitness and coverage.
- class pynguin.ga.computations.BranchDistanceTestCaseFitnessFunction(executor, code_object_id)[source]
A fitness function based on branch distances and entered code objects.
- compute_fitness(individual)[source]
Calculate the fitness value.
- Parameters:
individual – the chromosome to compute the fitness for.
- Returns:
DAR202
- Return type:
the new fitness # noqa
- compute_is_covered(individual)[source]
Compute if the goal of this fitness function is covered.
This computation is usually cheaper than computing the fitness, because we are not interested in the distance, but only a boolean result.
- Parameters:
individual – the chromosome to check coverage on.
- Return type:
- Returns:
True, if the goal of this fitness function is covered.
- class pynguin.ga.computations.BranchDistanceTestSuiteFitnessFunction(executor)[source]
A fitness function based on branch distances and entered code objects.
- compute_fitness(individual)[source]
Calculate the fitness value.
- Parameters:
individual – the chromosome to compute the fitness for.
- Returns:
DAR202
- Return type:
the new fitness # noqa
- compute_is_covered(individual)[source]
Compute if the goal of this fitness function is covered.
This computation is usually cheaper than computing the fitness, because we are not interested in the distance, but only a boolean result.
- Parameters:
individual – the chromosome to check coverage on.
- Return type:
- Returns:
True, if the goal of this fitness function is covered.
- is_maximisation_function()[source]
Do we need to maximise or minimise this function?
- Returns:
DAR202
- Return type:
Whether or not this is a maximisation function # noqa
- class pynguin.ga.computations.ChromosomeComputation(_executor)[source]
An abstract computation on chromosomes.
- class pynguin.ga.computations.ComputationCache(chromosome, *, fitness_functions=None, coverage_functions=None, fitness_cache=None, is_covered_cache=None, coverage_cache=None)[source]
Caches computation results and computes values on demand.
- add_coverage_function(coverage_function)[source]
Adds a coverage function.
- Parameters:
coverage_function (
CoverageFunction) – A fitness function- Return type:
- add_fitness_function(fitness_function)[source]
Adds the given fitness function.
- Parameters:
fitness_function (
FitnessFunction) – A fitness function- Return type:
- clone(new_chromosome)[source]
Create a deep copy of this cache.
- Parameters:
new_chromosome – The chromosome with which this cache is associated.
- Return type:
- Returns:
A deep copy.
- get_coverage()[source]
Provides the mean coverage value.
- Return type:
- Returns:
The mean coverage value
- get_coverage_for(coverage_function)[source]
Provides the coverage value for a certain coverage function.
- Parameters:
coverage_function (
CoverageFunction) – The fitness function whose coverage value shall be returned- Return type:
- Returns:
The coverage value for the fitness function
- get_coverage_functions()[source]
Provide the currently configured coverage functions of this chromosome.
- Return type:
- Returns:
The list of currently configured coverage functions.
- get_fitness()[source]
Provide a sum of the current fitness values.
- Return type:
- Returns:
The sum of the current fitness values
- get_fitness_for(fitness_function)[source]
Returns the fitness values of a specific fitness function.
- Parameters:
fitness_function (
FitnessFunction) – The fitness function- Return type:
- Returns:
Its fitness value
- get_fitness_functions()[source]
Provide the currently configured fitness functions of this chromosome.
- Return type:
- Returns:
The list of currently configured fitness functions
- get_is_covered(fitness_function)[source]
Check if the individual covers this fitness function.
- Parameters:
fitness_function (
FitnessFunction) – The fitness function to check- Return type:
- Returns:
True, iff the individual covers the fitness function.
- set_coverage_values(coverage_values)[source]
Sets the coverage values for the specific functions.
- Parameters:
coverage_values (
dict[CoverageFunction,float]) – A dictionary of coverage values, keyed by coverage function.- Return type:
- class pynguin.ga.computations.FitnessFunction[source]
Interface for a fitness function.
- abstract compute_fitness(individual)[source]
Calculate the fitness value.
- Parameters:
individual – the chromosome to compute the fitness for.
- Returns:
DAR202
- Return type:
the new fitness # noqa
- abstract compute_is_covered(individual)[source]
Compute if the goal of this fitness function is covered.
This computation is usually cheaper than computing the fitness, because we are not interested in the distance, but only a boolean result.
- Parameters:
individual – the chromosome to check coverage on.
- Return type:
- Returns:
True, if the goal of this fitness function is covered.
- class pynguin.ga.computations.LineTestSuiteFitnessFunction(_executor)[source]
A fitness function based on lines covered and entered code objects.
- compute_fitness(individual)[source]
Calculate the fitness value.
- Parameters:
individual – the chromosome to compute the fitness for.
- Returns:
DAR202
- Return type:
the new fitness # noqa
- compute_is_covered(individual)[source]
Compute if the goal of this fitness function is covered.
This computation is usually cheaper than computing the fitness, because we are not interested in the distance, but only a boolean result.
- Parameters:
individual – the chromosome to check coverage on.
- Return type:
- Returns:
True, if the goal of this fitness function is covered.
- class pynguin.ga.computations.StatementCheckedTestSuiteFitnessFunction(_executor)[source]
A fitness function for the checked statement coverage of test suites.
A fitness function based on lines included in the backward slice of each statement of a test suite.
- compute_fitness(individual)[source]
Calculate the fitness value.
- Parameters:
individual – the chromosome to compute the fitness for.
- Returns:
DAR202
- Return type:
the new fitness # noqa
- compute_is_covered(individual)[source]
Compute if the goal of this fitness function is covered.
This computation is usually cheaper than computing the fitness, because we are not interested in the distance, but only a boolean result.
- Parameters:
individual – the chromosome to check coverage on.
- Return type:
- Returns:
True, if the goal of this fitness function is covered.
- class pynguin.ga.computations.TestCaseAssertionCheckedCoverageFunction(_executor)[source]
Computes checked coverage on test cases with assertions.
- class pynguin.ga.computations.TestCaseBranchCoverageFunction(_executor)[source]
Computes branch coverage on test cases.
- class pynguin.ga.computations.TestCaseChromosomeComputation(_executor)[source]
A function that computes something on a test case chromosome.
- class pynguin.ga.computations.TestCaseCoverageFunction(_executor)[source]
Base class for all coverage functions that act on test case level.
- class pynguin.ga.computations.TestCaseFitnessFunction(executor, code_object_id)[source]
Base class for test case fitness functions.
- class pynguin.ga.computations.TestCaseLineCoverageFunction(_executor)[source]
Computes line coverage on test cases.
- class pynguin.ga.computations.TestCaseStatementCheckedCoverageFunction(_executor)[source]
Computes checked coverage on the statements of test cases.
- class pynguin.ga.computations.TestSuiteAssertionCheckedCoverageFunction(_executor)[source]
Computes checked coverage on test suites with assertions.
- class pynguin.ga.computations.TestSuiteBranchCoverageFunction(_executor)[source]
Computes branch coverage on test suites.
- class pynguin.ga.computations.TestSuiteChromosomeComputation(_executor)[source]
A function that computes something on a test suite chromosome.
- class pynguin.ga.computations.TestSuiteCoverageFunction(_executor)[source]
Base class for all coverage functions that act on test suite level.
- class pynguin.ga.computations.TestSuiteFitnessFunction(_executor)[source]
Base class for test suite fitness functions.
- class pynguin.ga.computations.TestSuiteLineCoverageFunction(_executor)[source]
Computes line coverage on test suites.
- class pynguin.ga.computations.TestSuiteStatementCheckedCoverageFunction(_executor)[source]
Computes checked coverage on the statements of test suites.
- pynguin.ga.computations.analyze_results(results)[source]
Merge the trace of the given results.
- Parameters:
results (
list[ExecutionResult]) – The list of execution results to analyze- Return type:
- Returns:
the merged traces.
- pynguin.ga.computations.compare(fitness_1, fitness_2)[source]
Compare the two specified values.
- Parameters:
- Return type:
- Returns:
the value 0 if fitness_1 is equal to fitness_2; a value less than 0 if fitness_1 is less than fitness_2; and a value greater than 0 if fitness_1 is greater than fitness_2
- pynguin.ga.computations.compute_assertion_checked_coverage(trace, subject_properties)[source]
Computes checked coverage on bytecode instructions.
Each assertion can be sliced, returning a list of instructions that are checked by an assertion. If we combine all lists of instructions returned by slicing all assertions, we get the combined dynamic slice of the test execution’s assertions. We then can map all instructions inside the slice to lines that are checked covered of the module under test. To calculate the coverage we can then divide the amount of lines checked covered through the test execution by the lines overall available in the module under test.
- Parameters:
trace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known data
- Return type:
- Returns:
The computed coverage value
- pynguin.ga.computations.compute_branch_coverage(trace, subject_properties)[source]
Computes branch coverage on bytecode instructions.
The resulting coverage should be equal to decision coverage on source code.
- Parameters:
trace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known data
- Return type:
- Returns:
The computed coverage value
- pynguin.ga.computations.compute_branch_distance_fitness(trace, subject_properties, exclude_code=None, exclude_true=None, exclude_false=None)[source]
Computes fitness based on covered branches and branch distances.
- Parameters:
trace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known dataexclude_code (
Optional[set[int]]) – Ids of the code objects that should not be considered.exclude_true (
Optional[set[int]]) – Ids of predicates whose True branch should not be considered.exclude_false (
Optional[set[int]]) – Ids of predicates whose False branch should not be considered.
- Return type:
- Returns:
The computed fitness value
- pynguin.ga.computations.compute_branch_distance_fitness_is_covered(trace, subject_properties, exclude_code=None, exclude_true=None, exclude_false=None)[source]
Computes if all branches and code objects have been executed.
- Parameters:
trace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known dataexclude_code (
Optional[set[int]]) – Ids of the code objects that should not be considered.exclude_true (
Optional[set[int]]) – Ids of predicates whose True branch should not be considered.exclude_false (
Optional[set[int]]) – Ids of predicates whose False branch should not be considered.
- Return type:
- Returns:
True, if all branches were covered
- pynguin.ga.computations.compute_checked_coverage_statement_fitness_is_covered(trace, subject_properties)[source]
Computes if all lines and code objects are checked by a return statement.
- Parameters:
trace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known data
- Return type:
- Returns:
True, if all lines were checked by a return, false otherwise
- pynguin.ga.computations.compute_line_coverage(trace, subject_properties)[source]
Computes line coverage on bytecode instructions.
- Parameters:
trace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known data
- Return type:
- Returns:
The computed coverage value
- pynguin.ga.computations.compute_line_coverage_fitness_is_covered(trace, subject_properties)[source]
Computes if all lines and code objects have been executed.
- Parameters:
trace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known data
- Return type:
- Returns:
True, if all lines were covered, false otherwise
- pynguin.ga.computations.compute_statement_checked_lines(statements, trace, subject_properties, statement_slicing_criteria)[source]
Computes checked coverage on bytecode instructions.
Each statement can be sliced, returning a list of instructions that are checked by the return value of the statement. If we combine all lists of instructions returned by slicing all statements, we get the combined dynamic slice of the test execution’s statements. We then can map all instructions inside the slice to lines that are checked covered of the module under test.
- Parameters:
statements (
list[Statement]) – The sliced instructionstrace (
ExecutionTrace) – The execution tracesubject_properties (
SubjectProperties) – All known datastatement_slicing_criteria (
dict[int,SlicingCriterion]) – a dictionary of statement positions and its slicing criteria
- Return type:
- Returns:
The checked line ids of lines checked by the statements
- pynguin.ga.computations.normalise(value)[source]
Normalise a value.
- Parameters:
value (
float) – The value to normalise- Return type:
- Returns:
The normalised value
- Raises:
RuntimeError – if the value is negative
pynguin.assertion.assertiongenerator
Provides an assertion generator.
- class pynguin.assertion.assertiongenerator.AssertionGenerator(plain_executor, filtering_executions=1)[source]
A simple assertion generator.
Creates all regression assertions.
pynguin.assertion.mutation_analysis.controller
Provides a controller for generating mutants.
- class pynguin.assertion.mutation_analysis.controller.MutationController(mutant_generator, module_ast, module)[source]
A controller that creates mutants.
- create_mutant(mutant_ast)[source]
Creates a mutant of the module.
- Parameters:
mutant_ast (
Module) – The mutant AST.- Return type:
- Returns:
The created mutant module.
- create_mutants()[source]
Creates mutants for the module.
- Return type:
Generator[tuple[ModuleType|None,list[Mutation]]]- Returns:
A generator of tuples where the first entry is the mutated module or None if the mutated module cannot be created and the second part is a list of all the mutations operators applied.
pynguin.assertion.mutation_analysis.mutators
Provides classes for mutating ASTs.
Based on https://github.com/se2p/mutpy-pynguin/blob/main/mutpy/controller.py and integrated in Pynguin.
- class pynguin.assertion.mutation_analysis.mutators.FirstOrderMutator(operators)[source]
A mutator that applies first order mutations.
- class pynguin.assertion.mutation_analysis.mutators.HighOrderMutator(operators, hom_strategy=None)[source]
A mutator that applies high order mutations.
pynguin.instrumentation.version.DynamicSeedingInstrumentation
Specialized instrumentation adapter for dynamic constant seeding in Python 3.10.
pynguin.utils.typetracing
Provides utilities to trace the usage of objects.
- class pynguin.utils.typetracing.DepthDefaultDict(depth)[source]
A dictionary creating a UsageTraceNode automatically for each key.
The implementation creates a UsageTraceNode for each requested and non-existing key.
- class pynguin.utils.typetracing.UsageTraceNode(name, depth=0, type_checks=<factory>, arg_types=<factory>, arg_values=<factory>)[source]
The knowledge gathered by a proxy.
- find_path(path)[source]
Check if this usage trace tree has the given path.
- Parameters:
- Return type:
- Returns:
The usage trace node at the end of the path, if it exists, otherwise None.
- static from_proxy(obj)[source]
Extract knowledge from the given proxy.
This is a convenience method, because the knowledge attribute is not visible on a proxy.
- Parameters:
obj (
ObjectProxy) – the proxy from which we should extract knowledge- Return type:
- Returns:
The extracted knowledge.
- merge(other)[source]
Merge the knowledge from the other proxy into this one.
- Parameters:
other (
UsageTraceNode) – The knowledge that should be merged into this one.- Return type:
- pynguin.utils.typetracing.proxify(*, log_args=False, no_wrap_return=False)[source]
Decorator method to trace the usage of a method on a proxy.
Unwraps the proxy.
Stores the access to the method
Stores the argument types if requested.
Stores the argument values if requested and if the type is in VALUE_TRACED_TYPES.
Wraps the result in a proxy object (unless requested otherwise).
- Parameters:
log_args – Should we store the arguments (types and values)?
no_wrap_return – Some cases, e.g., __int__ don’t allow a return value that is not an int, so in some cases we have to disable wrapping.
- Returns:
A decorated function