VOOZH about

URL: https://deepwiki.com/hypervel/foundation/6-testing-framework

⇱ Testing Framework | hypervel/foundation | DeepWiki


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

Testing Framework

Purpose and Scope

The Testing Framework provides a comprehensive PHPUnit-based testing infrastructure for Hypervel Foundation applications. It offers a trait-based architecture that composes testing capabilities for HTTP requests, console commands, database operations, authentication, and time manipulation. The framework handles Hyperf's coroutine execution model transparently, ensuring tests run correctly in both coroutine and non-coroutine contexts.

This document covers the overall testing framework architecture, the TestCase base class, trait composition, and lifecycle management. For detailed documentation on specific testing capabilities, see:

  • HTTP request testing: 6.2
  • Response assertions: 6.3
  • Console command testing: 6.4
  • Database testing: 6.5
  • Authentication and session testing: 6.6

Architecture Overview

The testing framework is built on a modular trait-based architecture where the TestCase base class composes multiple testing concerns through traits. Each trait provides a specific domain of testing functionality, allowing test classes to inherit only the capabilities they need.

Trait Composition Architecture


Diagram: TestCase Trait Composition Structure

The TestCase class src/Testing/TestCase.php24 extends PHPUnit's base test case and uses eight core traits src/Testing/TestCase.php26-33:

TraitPurposeDetails
InteractsWithContainerContainer and application managementApplication creation, refresh, and service binding
MakesHttpRequestsHTTP request simulationGET, POST, PUT, DELETE, etc. with middleware control
InteractsWithAuthenticationAuthentication testingActing as users, authentication assertions
InteractsWithConsoleConsole command testingCommand execution, output mocking
InteractsWithDatabaseDatabase utilitiesSeeding, querying, transaction management
InteractsWithSessionSession manipulationSession data setting and assertions
InteractsWithTimeTime manipulationFreezing, traveling through time using Carbon
MocksApplicationServicesService mockingCreating mocks and spies for application services

Additionally, test classes can opt-in to specialized traits (shown as dashed lines) for specific behaviors:

  • RefreshDatabase: Migrates and resets database between tests
  • DatabaseMigrations: Runs migrations before tests
  • DatabaseTransactions: Wraps tests in database transactions
  • WithoutMiddleware: Disables middleware for all tests in the class
  • WithoutEvents: Disables event dispatching for all tests

Sources: src/Testing/TestCase.php24-33 src/Testing/TestCase.php84-102

Testing Component Relationships


Diagram: Testing Component Object Relationships

The TestCase interacts with the Application container to create an isolated test environment. HTTP testing flows through TestClient, which uses Waiter to manage coroutine execution and produces TestResponse objects. Console testing uses PendingCommand to mock command execution. Database testing traits directly interact with the application's database connections and migration system.

Sources: src/Testing/TestCase.php1-197 src/Testing/TestResponseAssert.php1-134

TestCase Foundation

The TestCase class src/Testing/TestCase.php24 serves as the base class for all application tests. It extends PHPUnit\Framework\TestCase and provides:

  1. Application Lifecycle Management: Creates, refreshes, and destroys the application container between tests
  2. Coroutine Execution: Ensures tests run correctly within Hyperf's coroutine context
  3. Trait Bootstrapping: Automatically discovers and initializes trait-specific setup methods
  4. Lifecycle Hooks: Provides callbacks for post-creation and pre-destruction phases
  5. Cleanup Management: Handles Mockery, Facade, and Carbon cleanup

Key Properties

protected array $afterApplicationCreatedCallbacks // Callbacks run after app creation
protected array $beforeApplicationDestroyedCallbacks // Callbacks run before app destruction
protected ?Throwable $callbackException // Exception from cleanup callbacks
protected bool $setUpHasRun // Tracks setUp completion

Sources: src/Testing/TestCase.php36-53

Test Lifecycle

The test lifecycle follows PHPUnit's standard pattern with Hypervel-specific enhancements for coroutine management and trait bootstrapping.


Diagram: Test Execution Lifecycle with Method Calls

setUp Phase

The setUp() method src/Testing/TestCase.php55-73 executes the following sequence:

  1. Clear Facades: Facade::clearResolvedInstances() resets all facade instances src/Testing/TestCase.php57
  2. Initialize Application: If $this->app is not set, calls refreshApplication() src/Testing/TestCase.php60-62
  3. Bootstrap Traits: Executes setUpTraits() within a coroutine context src/Testing/TestCase.php64-66
  4. Run Callbacks: Executes all registered afterApplicationCreatedCallbacks src/Testing/TestCase.php68-70
  5. Mark Complete: Sets $this->setUpHasRun = true src/Testing/TestCase.php72

setUpTraits Phase

The setUpTraits() method src/Testing/TestCase.php80-115 uses reflection to discover and bootstrap traits:

  1. Discover Traits: Uses class_uses_recursive() to find all traits in the class hierarchy src/Testing/TestCase.php82
  2. Bootstrap Special Traits: Checks for and initializes opt-in traits:
  3. Convention-Based Setup: For each trait, calls setUp{TraitName}() if it exists src/Testing/TestCase.php104-107
  4. Register Teardown: For each trait, registers tearDown{TraitName}() as a before-destruction callback if it exists src/Testing/TestCase.php109-111

tearDown Phase

The tearDown() method src/Testing/TestCase.php117-152 performs cleanup:

  1. Pre-Destruction Callbacks: Executes callBeforeApplicationDestroyedCallbacks() in a coroutine src/Testing/TestCase.php120-122
  2. Flush Application: Calls flushApplication() to clean up the container src/Testing/TestCase.php123
  3. Flush Coroutines: Calls Coroutine::flushAfterCreated() to clean up Hyperf coroutine state src/Testing/TestCase.php125
  4. Clear Callbacks: Resets callback arrays src/Testing/TestCase.php128-129
  5. Handle Exceptions: Throws any exception caught during callback execution src/Testing/TestCase.php131-133
  6. Cleanup Mockery: Closes Mockery container and adds expectation counts src/Testing/TestCase.php135-141
  7. Reset Time: Calls Carbon::setTestNow() and CarbonImmutable::setTestNow() to clear time mocking src/Testing/TestCase.php143-149
  8. Mark Incomplete: Sets $this->setUpHasRun = false src/Testing/TestCase.php151

Sources: src/Testing/TestCase.php55-152

Coroutine Management

Hyperf's architecture requires many operations to execute within a coroutine context. The testing framework provides transparent coroutine management through the runInCoroutine() helper method.

runInCoroutine Method


This method src/Testing/TestCase.php193-196 checks if the current execution context is already in a coroutine using Coroutine::inCoroutine(). If true, it executes the callback directly. If false, it wraps the callback in run() to create a coroutine context.

Usage in TestCase:

This ensures that trait setup methods, database operations, and cleanup callbacks execute correctly regardless of the test's execution context.

Sources: src/Testing/TestCase.php193-196

Lifecycle Hooks

The testing framework provides two types of lifecycle hooks for custom initialization and cleanup logic.

After Application Created

The afterApplicationCreated() method src/Testing/TestCase.php157-164 registers callbacks to run after the application is created and all traits are bootstrapped.

Behavior:

Use Cases:

  • Setting up test-specific service bindings
  • Seeding test data
  • Configuring mocks or spies

Before Application Destroyed

The beforeApplicationDestroyed() method src/Testing/TestCase.php169-172 registers callbacks to run before the application is destroyed and cleaned up.

Exception Handling: The callBeforeApplicationDestroyedCallbacks() method src/Testing/TestCase.php177-188 wraps each callback in a try-catch block. The first exception encountered is stored in $this->callbackException src/Testing/TestCase.php182-185 and re-thrown after all callbacks complete src/Testing/TestCase.php131-133 This ensures all cleanup callbacks execute even if one fails.

Use Cases:

  • Rolling back database transactions
  • Cleaning up temporary files
  • Resetting global state
  • Verifying mock expectations

Sources: src/Testing/TestCase.php157-188

Test Response Assertions

The framework provides enhanced assertion capabilities through the TestResponseAssert class, which decorates PHPUnit assertions with additional response context.

TestResponseAssert Architecture


Diagram: TestResponseAssert Delegation Pattern

The TestResponseAssert class src/Testing/TestResponseAssert.php18 acts as a decorator for Hyperf's Assert class, intercepting assertion failures to inject response context.

Magic Method Delegation

The class uses __call() src/Testing/TestResponseAssert.php40-47 to proxy all method calls to Assert:

  1. Call the assertion method on Assert
  2. If an ExpectationFailedException is thrown, catch it
  3. Inject response context via injectResponseContext() src/Testing/TestResponseAssert.php62-73
  4. Re-throw the decorated exception

Response Context Injection

When assertions fail, the injectResponseContext() method src/Testing/TestResponseAssert.php62-73 examines the response:

For JSON Responses:

This provides immediate visibility into validation errors when assertions fail, eliminating the need to manually inspect response content.

Error Formatting

The appendErrorsToException() method src/Testing/TestResponseAssert.php100-118 formats errors:

For JSON errors:

For array errors:

Deduplication:

The formatted errors are prepended to the exception message with a clear header src/Testing/TestResponseAssert.php111-115

Sources: src/Testing/TestResponseAssert.php1-134

Authentication Testing

The InteractsWithAuthentication trait src/Testing/Concerns/InteractsWithAuthentication.php10 provides methods for testing authentication scenarios.

Acting As User

MethodPurposeParameters
actingAs()Set the authenticated userUserContract $user, ?string $guard = null
be()Alias for actingAs()UserContract $user, ?string $guard = null

Both methods src/Testing/Concerns/InteractsWithAuthentication.php15-37 perform the same operation:

  1. Clear the wasRecentlyCreated flag if present src/Testing/Concerns/InteractsWithAuthentication.php25-27
  2. Set the user on the specified guard via AuthFactoryContract src/Testing/Concerns/InteractsWithAuthentication.php29-31
  3. Set the guard as the default via shouldUse() src/Testing/Concerns/InteractsWithAuthentication.php33-34

Authentication Assertions

MethodAssertionParameters
assertAuthenticated()User is authenticated?string $guard = null
assertGuest()User is not authenticated?string $guard = null
assertAuthenticatedAs()User is authenticated as specific userUserContract $user, ?string $guard = null
assertCredentials()Credentials are validarray $credentials, ?string $guard = null
assertInvalidCredentials()Credentials are invalidarray $credentials, ?string $guard = null

Implementation Details:

Sources: src/Testing/Concerns/InteractsWithAuthentication.php1-137

Integration with PHPUnit

The TestCase class seamlessly integrates with PHPUnit's testing framework while adding Hypervel-specific functionality:

PHPUnit Compatibility

  • Extends PHPUnit TestCase: Direct inheritance from PHPUnit\Framework\TestCase src/Testing/TestCase.php24
  • Standard Lifecycle: Uses PHPUnit's setUp() and tearDown() hooks
  • Assertion Methods: All PHPUnit assertions are available through inheritance
  • Test Discovery: Works with PHPUnit's standard test discovery mechanisms

Mockery Integration

The framework integrates with Mockery for mocking:

  1. Expectation Counting: Adds Mockery expectation counts to PHPUnit's assertion count src/Testing/TestCase.php136-138
  2. Container Cleanup: Closes the Mockery container in tearDown() src/Testing/TestCase.php140
  3. Verification: Ensures mock expectations are verified even if the test passes

Test Isolation

Each test runs in isolation through:

Sources: src/Testing/TestCase.php24 src/Testing/TestCase.php135-149

Summary

The Testing Framework provides a modular, trait-based architecture for testing Hypervel Foundation applications. The TestCase base class orchestrates test execution through a well-defined lifecycle, manages coroutine contexts transparently, and integrates with PHPUnit and Mockery. The framework's trait composition allows tests to include only the functionality they need, while the assertion utilities provide enhanced error context for faster debugging.

For detailed information on specific testing capabilities, refer to the child pages:

  • 6.1 Test Case Foundation and Lifecycle
  • 6.2 HTTP Request Testing
  • 6.3 Test Response Assertions
  • 6.4 Console Command Testing
  • 6.5 Database Testing Utilities
  • 6.6 Authentication and Session Testing

Sources: src/Testing/TestCase.php1-197 src/Testing/TestResponseAssert.php1-134 src/Testing/Concerns/InteractsWithAuthentication.php1-137