metafunc.py
Overview
The [metafunc.py](/projects/286/67337) file is a comprehensive test suite module primarily focused on testing the behavior and functionality of the `python.Metafunc` class within the pytest testing framework. The `Metafunc` object in pytest represents the test function's meta-information during test collection and generation phases, enabling dynamic test parameterization and fixture interaction.
This file contains an extensive set of unit and functional tests that validate core features such as:
Parameterizing test functions with different argument values.
Handling of indirect parametrization (parameters passed through fixtures).
Generation and uniqueness of test IDs for parametrized tests.
Proper scope determination for fixtures and parameters.
Integration and interaction with pytest markers like
xfail.Error handling during parametrization.
Support for Unicode, bytes, and complex id generation.
Interaction with pytest's
pytest_generate_testshook.Ensuring correct behavior with multiple parametrizations and nested scopes.
Testing special features like hidden parameters in test IDs.
The file uses mock objects to simulate parts of pytest internals for unit testing and leverages pytest's own testing utilities (`Pytester`) for integration-style tests.
Detailed Explanation of Classes and Methods
Class: TestMetafunc
This class contains unit tests for the core functionalities of the `python.Metafunc` class, focusing on correctness of parameterization logic and ID generation.
Method: Metafunc(self, func, config=None) -> python.Metafunc
Purpose: Helper factory method to create a minimal
Metafuncinstance for a given function to facilitate testing.Parameters:
func: The test function to be wrapped byMetafunc.config: Optional pytest config object.
Returns: An instance of
python.Metafunc.Usage Example:
metafunc = TestMetafunc().Metafunc(my_test_function)Implementation Detail: Uses several inner mock classes (
FuncFixtureInfoMock,FixtureManagerMock,SessionMock,DefinitionMock) to simulate pytest internals without requiring full pytest initialization.
Test Methods Overview
The class contains many test methods, each testing specific aspects of `Metafunc`. Highlights include:
test_no_funcargs: Verifies that functions with no arguments have no fixtures.test_function_basic: Tests basic fixture name extraction from function signature.test_parametrize_error: Confirms that repeated parameterization of the same argument raises errors.test_parametrize_error_iterator: Handles errors arising from invalid IDs when IDs are given as an iterator.test_parametrize_bad_scope: Checks that invalid scope strings raise exceptions.test_parametrize_request_name: Ensures the reserved namerequestcannot be used as a parameter.test_find_parametrized_scope: Unit test for_find_parametrized_scopeutility to find the narrowest scope among parametrized fixtures.test_parametrize_and_id: Tests combined parametrization of multiple arguments and ID generation.test_unicode_idvaland related tests: Verify proper escaping and handling of Unicode and bytes in IDs.test_idmaker_autonameand related tests: Test theIdMakerclass for generating unique, human-readable IDs from parameters.test_parametrize_indirectand variations: Test indirect parametrization where parameters are passed via fixtures.test_parametrize_uses_no_fixture_error_*: Verify errors when parameters are provided but no matching fixture exists.test_high_scoped_parametrize_reordering: Ensures correct test ordering when parametrization scopes differ.test_parametrize_multiple_times: Tests that multiple parametrize marks combine correctly.test_parametrize_class_scenarios: Example test for parametrizing based on class-level scenarios.test_parametrize_ids_exception: Tests behavior when ID generation raises exceptions.test_parametrize_ids_returns_non_string: Ensures IDs returned from callable can be non-string but still handled gracefully.test_parametrize_with_identical_ids_get_unique_names: Confirms that duplicate IDs are made unique by suffixing.
Class: TestMetafuncFunctional
This class consists of functional tests that primarily use pytest's `Pytester` utility to run tests in isolated environments and verify pytest's behavior end-to-end.
Key test behaviors:
Verify that
Metafuncattributes likeconfig,module,function, andclsare properly set.Test multiple functions and classes with parametrized arguments.
Confirm indirect parametrization and fixture interaction.
Check behavior of
pytest_generate_testshook for dynamically generating parameters.Test various parametrize patterns including positional arguments, multiple parameters, and markers.
Integration tests for ID generation and uniqueness.
Tests for handling Unicode, bytes, and special parameter values.
Validate test collection and execution results with different parametrization schemes.
Class: TestMetafuncFunctionalAuto
Focused on tests related to automatic scope detection for parametrized tests.
Tests how fixture scopes influence parametrization scope.
Tests indirect parametrization with automatic and explicit scopes.
Ensures that autouse fixtures and different scopes are respected during test generation.
Validates that parametrization scope overrides and default behaviors function correctly.
Class: TestMarkersWithParametrization
Tests the interaction between pytest markers (e.g., `xfail`, user-defined marks) and parametrized tests.
Validates that markers applied to
pytest.paraminstances affect test outcomes properly.Tests selection of tests based on marks.
Verifies skip, xfail, and strict xfail behaviors combined with parametrization.
Checks that multiple marks and marker arguments/keywords are handled correctly.
Class: TestHiddenParam
Tests the feature of `pytest.HIDDEN_PARAM` which allows hiding certain parameter sets from test IDs.
Ensures hidden parameters cause test names to omit the corresponding parameter.
Confirms multiple hidden parameters in the same parametrize call raises errors due to uniqueness constraints.
Tests behavior of multiple parametrize decorators with hidden parameters.
Important Implementation Details and Algorithms
Mocking Pytest Internals: The
Metafuncfactory uses lightweight mocks to simulate parts of pytest's fixture management and function definitions, enabling isolated unit tests without requiring full pytest runtime.IDMaker Usage: The
IdMakerclass (imported from_pytest.python) is extensively tested here for generating unique human-readable IDs for parameter sets. It handles escaping Unicode, bytes, and complex objects, as well as uniqueness enforcement and user-supplied IDs/functions.Parametrization Expansion: Tests cover how multiple
parametrizecalls combine via cartesian product of parameters, how scopes affect fixture sharing, and how indirect parametrization integrates with fixtures.Error Handling: The tests verify robust error detection for common mistakes such as repeated parameterization of the same argument, invalid scopes, and misuse of reserved names.
Use of Hypothesis: Property-based testing (
hypothesis) is used to validate theIdMaker's_idvalmethod for a wide range of inputs ensuring that generated IDs are valid ASCII strings.Integration via
Pytester: Functional tests leverage pytest'sPytestertool to create temporary test files and run pytest, verifying actual test collection, execution, and reporting behavior.
Interaction with Other System Components
python.Metafunc: The central class under test here, used by pytest during test collection to introspect test functions, discover fixtures, and generate parametrized test cases.IdMaker: Used for generating unique IDs for each parameter set to be shown in test case names.fixtures.FixtureDefand Fixture Management: Parametrization and scope determination relate closely to fixture definitions and their scopes.pytestMarkers: The file tests how markers likexfailand user-defined marks affect parametrized tests.pytest_generate_testsHook: Tested extensively for dynamic test generation scenarios.PytesterUtility: Used for integration testing by creating temporary test scripts and running pytest itself.
Visual Diagram
classDiagram
class TestMetafunc {
+Metafunc(func, config=None) python.Metafunc
+test_no_funcargs()
+test_function_basic()
+test_parametrize_error()
+test_parametrize_error_iterator()
+test_parametrize_bad_scope()
+test_parametrize_request_name()
+test_find_parametrized_scope()
+test_parametrize_and_id()
+test_unicode_idval()
+test_idmaker_autoname()
+test_parametrize_indirect()
+test_parametrize_uses_no_fixture_error_indirect_false()
+test_high_scoped_parametrize_reordering()
+test_parametrize_multiple_times()
+test_parametrize_class_scenarios()
+test_parametrize_ids_exception()
+test_parametrize_with_identical_ids_get_unique_names()
}
class TestMetafuncFunctional {
+test_attributes(pytester)
+test_two_functions(pytester)
+test_generate_tests_in_class(pytester)
+test_parametrize_functional2(pytester)
+test_parametrize_and_inner_getfixturevalue(pytester)
+test_parametrize_with_ids(pytester)
+test_parametrize_iterator(pytester)
...
}
class TestMetafuncFunctionalAuto {
+test_parametrize_auto_scope(pytester)
+test_parametrize_auto_scope_indirect(pytester)
+test_parametrize_all_indirects(pytester)
+test_parametrize_some_arguments_auto_scope(pytester)
+test_parametrize_issue634(pytester)
}
class TestMarkersWithParametrization {
+test_simple_mark(pytester)
+test_select_based_on_mark(pytester)
+test_simple_xfail(pytester)
+test_parametrize_called_in_generate_tests(pytester)
+test_parametrize_ID_generation_string_int_works(pytester)
+test_parametrize_marked_value(pytester)
}
class TestHiddenParam {
+test_parametrize_ids(pytester)
+test_param_id(pytester)
+test_multiple_hidden_param_is_forbidden(pytester)
+test_multiple_hidden_param_is_forbidden_idmaker()
+test_multiple_parametrize(pytester)
}
%% Relationships
TestMetafunc ..> python.Metafunc : tests
TestMetafunc ..> IdMaker : uses
TestMetafuncFunctional ..> Pytester : uses
TestMarkersWithParametrization ..> pytest.mark : tests interaction
TestHiddenParam ..> pytest.HIDDEN_PARAM : tests feature
Summary
The [metafunc.py](/projects/286/67337) file is a critical pytest internal testing module that extensively tests the `Metafunc` class and related parametrization features. Through a combination of unit tests (with mocks), property-based tests, and integration tests (using `Pytester`), it ensures robust and correct behavior of test parameterization, ID generation, scope determination, and marker handling in pytest.
This module helps verify that:
Parametrized test functions are correctly expanded into individual tests.
Test IDs are unique, meaningful, and handle complex data types gracefully.
Indirect parametrization integrates correctly with fixtures.
Markers like
xfailand user marks function properly with parametrization.Common errors are caught early with clear messages.
The pytest test collection and execution pipeline correctly respects parametrization scopes.
By rigorously testing these behaviors, this file helps maintain and improve pytest's powerful and flexible parameterization capabilities.