VOOZH about

URL: https://deepwiki.com/hypervel/foundation/6.2-test-attributes-and-extensibility

⇱ Test Attributes and Extensibility | hypervel/foundation | DeepWiki


Loading...
Last indexed: 7 February 2026 (101eff)
Menu

Test Attributes and Extensibility

Purpose and Scope

This document covers the attribute-based testing system in Hypervel Foundation, which provides declarative test configuration through PHP 8 attributes and extensible lifecycle hooks. The system enables test cases to be configured using attributes that are automatically discovered and executed at appropriate points in the test lifecycle.

For information about the base TestCase class and overall test lifecycle, see Test Case Foundation and Lifecycle. For specific testing concerns like HTTP request testing or container interaction, see sections 6.3 through 6.8.

Attribute System Architecture

The attribute system is built around two core components: the InteractsWithTestCase trait that manages attribute discovery and execution, and the AttributeParser class that extracts attributes from reflection metadata.


Sources: src/Testing/Concerns/InteractsWithTestCase.php1-245 src/Testing/AttributeParser.php1-114

Attribute Contracts

The testing framework defines several interfaces that attributes can implement to participate in the test lifecycle:

ContractPurposeLifecycle PhaseMethods
TestingFeatureBase marker interfaceN/ANone
ResolvableMeta-attributes that resolve to concrete attributesDiscoveryresolve(): ?TestingFeature
InvokableDirect invocation with application containerBefore Each__invoke(Application $app)
ActionableComplex setup with callback accessBefore Eachhandle(Application $app, Closure $callback)
BeforeEachPre-test setupBefore EachbeforeEach(Application $app)
AfterEachPost-test teardownAfter EachafterEach(Application $app)
BeforeAllClass-level setupBefore ClassbeforeAll()
AfterAllClass-level teardownAfter ClassafterAll()

Sources: src/Testing/Concerns/InteractsWithTestCase.php10-16

Attribute Discovery and Caching

The InteractsWithTestCase trait maintains several static caches to optimize attribute discovery:


Cache Data Structures

The caching system uses four static properties to store discovered attributes:

Class Attributes Cache

cachedTestCaseClassAttributes[className] = [
 ['key' => AttributeClassName, 'instance' => attributeInstance],
 ...
]

src/Testing/Concerns/InteractsWithTestCase.php27-31

Method Attributes Cache

cachedTestCaseMethodAttributes["ClassName:methodName"] = [
 ['key' => AttributeClassName, 'instance' => attributeInstance],
 ...
]

src/Testing/Concerns/InteractsWithTestCase.php33-38

Programmatic Features (cleared between tests)

testCaseTestingFeatures[] = ['key' => ..., 'instance' => ...]
testCaseMethodTestingFeatures[] = ['key' => ..., 'instance' => ...]

src/Testing/Concerns/InteractsWithTestCase.php40-52

Sources: src/Testing/Concerns/InteractsWithTestCase.php27-59

Attribute Resolution Process

The AttributeParser class handles the extraction and validation of attributes from PHP reflection metadata:


Attribute Validation

The validAttribute() method ensures only valid testing attributes are processed:


src/Testing/AttributeParser.php77-91

Resolvable Attributes

Resolvable attributes act as meta-attributes that transform into concrete testing features. For example, the Define attribute:


Sources: src/Testing/Attributes/Define.php1-38 src/Testing/AttributeParser.php94-112

Test Lifecycle Integration

The attribute system integrates with PHPUnit's lifecycle through specific hook methods in InteractsWithTestCase:


Setup Phase Execution Order

During setUp(), attributes are executed in the following order:

  1. Invokable attributes - Direct invocation with application container
  2. Actionable attributes - Complex setup with potential deferred execution
  3. BeforeEach attributes - Standard pre-test hooks

src/Testing/Concerns/InteractsWithTestCase.php173-204

Actionable Attribute Execution

Actionable attributes receive a callback to invoke test methods and may return a Closure for deferred execution:


This pattern allows attributes to delegate work back to test methods while optionally deferring some operations until after all attributes have been processed.

src/Testing/Concerns/InteractsWithTestCase.php187-198

Sources: src/Testing/Concerns/InteractsWithTestCase.php173-244

Programmatic Feature Addition

Tests can add attributes programmatically using the usesTestingFeature() method, which is useful for test base classes or shared test traits:


API Signature


The $flag parameter controls whether the attribute applies to all tests in the class (TARGET_CLASS) or only to specific methods (TARGET_METHOD).

src/Testing/Concerns/InteractsWithTestCase.php87-113

Usage Example Pattern


Sources: src/Testing/Concerns/InteractsWithTestCase.php87-113

Cache Lifecycle Management

The attribute caching system has specific cleanup points to prevent memory leaks and stale data:

CacheCleared WhenRationale
$testCaseMethodTestingFeaturesAfter each test methodMethod-level programmatic features are test-specific
$testCaseTestingFeaturesAfter all tests in classClass-level features can be reused across methods
$cachedTestCaseClassAttributesAfter all tests in classClass metadata is static but should not persist between test classes
$cachedTestCaseMethodAttributesAfter all tests in classMethod metadata is static but should not persist between test classes
$cachedTestCaseUsesAfter all tests in classTrait usage is static per class

src/Testing/Concerns/InteractsWithTestCase.php209-244

Trait Detection System

The usesTestingConcern() method allows tests to conditionally execute code based on which traits are in use:


This is primarily used internally by the testing framework to determine which features are available, such as checking if a test uses InteractsWithDatabase before attempting database operations.

src/Testing/Concerns/InteractsWithTestCase.php62-85

Sources: src/Testing/Concerns/InteractsWithTestCase.php62-85

Built-in Attribute Example: ResetRefreshDatabaseState

The framework includes several built-in attributes. The ResetRefreshDatabaseState attribute demonstrates the lifecycle pattern:


This attribute:

  • Targets classes only (TARGET_CLASS)
  • Implements both BeforeAll and AfterAll
  • Resets static database state before and after all tests in a class
  • Ensures clean state for database testing

src/Testing/Attributes/ResetRefreshDatabaseState.php1-44

Attribute Merging Priority

When multiple sources provide the same attribute type, they are merged in this priority order (later sources can add additional instances):

  1. Programmatic class features (testCaseTestingFeatures)
  2. Cached class attributes (from PHP attributes on class and parent classes)
  3. Programmatic method features (testCaseMethodTestingFeatures)
  4. Cached method attributes (from PHP attributes on method)

All attributes of the same class are grouped together, allowing multiple instances of repeatable attributes to execute in sequence.

src/Testing/Concerns/InteractsWithTestCase.php137-144

Sources: src/Testing/Concerns/InteractsWithTestCase.php120-170

Code-to-Feature Mapping


Sources: src/Testing/Concerns/InteractsWithTestCase.php1-245 src/Testing/AttributeParser.php1-114