pytest_test_categories.suggestion

Suggestion collector for auto-categorization analysis.

This module provides the SuggestionCollector service and related data structures for collecting resource usage observations and generating test category suggestions.

The collector operates in “observation mode” during test execution: - Records resource access patterns (network, filesystem, subprocess, etc.) - Records execution times - Tracks current test size markers

After test execution, the collector can generate suggestions for appropriate test size categories based on observed behavior.

Example

>>> collector = SuggestionCollector()
>>> collector.record_observation(
...     'test_api.py::test_fetch',
...     ResourceType.NETWORK,
...     'Connection to example.com:443'
... )
>>> collector.record_execution_time('test_api.py::test_fetch', 0.5)
>>> collector.record_current_size('test_api.py::test_fetch', TestSize.SMALL)
>>> # Later: generate suggestions based on observations

See also

  • violation_tracking.py: Similar pattern for tracking violations

  • services/hermeticity_summary.py: Similar pattern for summary output

Attributes

Classes

ResourceObservation

Immutable record of a resource access observation.

ResourceType

Types of external resources that tests may access.

SuggestionCollector

Service for collecting resource observations and generating suggestions.

TestSuggestion

Immutable record of a test size suggestion.

Module Contents

class pytest_test_categories.suggestion.ResourceObservation(/, **data)[source]

Bases: pydantic.BaseModel

Immutable record of a resource access observation.

Captures information about a resource access for analysis purposes. The record is immutable (frozen) to ensure it cannot be modified after creation.

Parameters:

data (Any)

resource_type[source]

The type of resource accessed.

details[source]

Human-readable description of the access.

Example

>>> observation = ResourceObservation(
...     resource_type=ResourceType.NETWORK,
...     details='Connection to example.com:443',
... )

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

details: str[source]
resource_type: ResourceType[source]
class pytest_test_categories.suggestion.ResourceType[source]

Bases: enum.StrEnum

Types of external resources that tests may access.

Each resource type corresponds to a category that affects the appropriate test size classification.

NETWORK[source]

Network access (socket connections)

FILESYSTEM[source]

Filesystem access outside temp dirs

SUBPROCESS[source]

Subprocess spawning

DATABASE[source]

Database connections

SLEEP[source]

Sleep/timing function calls

Initialize self. See help(type(self)) for accurate signature.

DATABASE = 'database'[source]
FILESYSTEM = 'filesystem'[source]
NETWORK = 'network'[source]
SLEEP = 'sleep'[source]
SUBPROCESS = 'subprocess'[source]
class pytest_test_categories.suggestion.SuggestionCollector[source]

Service for collecting resource observations and generating suggestions.

This collector operates in “observation mode” during test execution, recording resource access patterns without blocking them. After execution, it can generate suggestions for appropriate test size categories.

The collector tracks: - Resource observations (network, filesystem, subprocess, database, sleep) - Execution times for each test - Current size markers for each test

Example

>>> collector = SuggestionCollector()
>>> collector.record_observation('test.py::test_fn', ResourceType.NETWORK, 'details')
>>> collector.record_execution_time('test.py::test_fn', 0.5)
>>> collector.record_current_size('test.py::test_fn', TestSize.SMALL)
>>> collector.has_observations
True

Initialize an empty suggestion collector.

generate_suggestions()[source]

Generate test size suggestions based on collected observations.

Analyzes all recorded tests and generates suggestions for tests that: - Are uncategorized (no size marker) - Have a size marker that doesn’t match their observed behavior

Categorization rules: - No external resources + <100ms -> SMALL - No external resources + <1s -> SMALL - External resources OR >1s -> MEDIUM - Multiple resource types OR >5min -> LARGE

Returns:

List of TestSuggestion instances for tests needing categorization changes.

Return type:

list[TestSuggestion]

get_all_test_nodeids()[source]

Get all test nodeids that have been recorded.

Returns:

Set of all test nodeids with any recorded data.

Return type:

set[str]

get_current_size(test_nodeid)[source]

Get the current size marker for a specific test.

Parameters:

test_nodeid (str) – The pytest node ID of the test.

Returns:

The current size marker, or None if not recorded or uncategorized.

Return type:

pytest_test_categories.types.TestSize | None

get_execution_time(test_nodeid)[source]

Get the execution time for a specific test.

Parameters:

test_nodeid (str) – The pytest node ID of the test.

Returns:

The execution time in seconds, or None if not recorded.

Return type:

float | None

get_observations(test_nodeid)[source]

Get all observations for a specific test.

Parameters:

test_nodeid (str) – The pytest node ID of the test.

Returns:

List of ResourceObservation instances for the specified test.

Return type:

list[ResourceObservation]

get_test_observation_count(test_nodeid)[source]

Get the number of observations for a specific test.

Parameters:

test_nodeid (str) – The pytest node ID of the test.

Returns:

Number of observations for the specified test.

Return type:

int

record_current_size(test_nodeid, size)[source]

Record the current size marker of a test.

Parameters:
Return type:

None

record_execution_time(test_nodeid, duration_seconds)[source]

Record execution time for a test.

Parameters:
  • test_nodeid (str) – The pytest node ID of the test.

  • duration_seconds (float) – The test execution time in seconds.

Return type:

None

record_observation(test_nodeid, resource_type, details)[source]

Record a resource access observation for a test.

Parameters:
  • test_nodeid (str) – The pytest node ID of the test.

  • resource_type (ResourceType) – The type of resource accessed.

  • details (str) – Human-readable description of the access.

Return type:

None

property has_observations: bool[source]

Check if any observations have been recorded.

Returns:

True if at least one observation has been recorded.

Return type:

bool

property observation_count: int[source]

Get the total number of observations across all tests.

Returns:

Total count of all recorded observations.

Return type:

int

class pytest_test_categories.suggestion.TestSuggestion(/, **data)[source]

Bases: pydantic.BaseModel

Immutable record of a test size suggestion.

Captures the suggestion for a test’s appropriate size category based on observed behavior.

Parameters:

data (Any)

test_nodeid[source]

The pytest node ID of the test.

current_size[source]

The current size marker, or None if uncategorized.

suggested_size[source]

The suggested size based on observations.

reason[source]

Human-readable explanation for the suggestion.

Example

>>> suggestion = TestSuggestion(
...     test_nodeid='test_api.py::test_fetch',
...     current_size=TestSize.SMALL,
...     suggested_size=TestSize.MEDIUM,
...     reason='network access detected',
... )

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

current_size: pytest_test_categories.types.TestSize | None[source]
reason: str[source]
suggested_size: pytest_test_categories.types.TestSize[source]
test_nodeid: str[source]
pytest_test_categories.suggestion.MULTIPLE_RESOURCE_TYPES_THRESHOLD = 2[source]
pytest_test_categories.suggestion.SLOW_TEST_THRESHOLD_SECONDS = 1.0[source]
pytest_test_categories.suggestion.VERY_SLOW_TEST_THRESHOLD_SECONDS = 300[source]