VOOZH about

URL: https://deepwiki.com/hypervel/testbench/9.2-custom-testing-traits

⇱ Custom Testing Traits | hypervel/testbench | DeepWiki


Loading...
Last indexed: 7 February 2026 (93289f)
Menu

Custom Testing Traits

Purpose and Scope

This document guides developers in creating custom testing traits that extend TestCase functionality for package-specific testing needs. Custom traits allow you to encapsulate reusable test setup logic, define lifecycle hooks, and provide clean APIs for common testing patterns in your packages.

For detailed documentation on the three built-in testing traits, see Testing Traits and Concerns. For information about the core TestCase lifecycle and hooks, see TestCase: Core Testing Foundation.


Trait Composition Architecture

The testbench uses a trait-based composition pattern to extend TestCase functionality without requiring deep inheritance hierarchies. This architecture allows developers to mix and match testing concerns as needed.


Sources: src/Concerns/HandlesRoutes.php1-49 src/Concerns/CreatesApplication.php1-60 src/Concerns/HandlesDatabases.php1-56


Anatomy of a Testing Trait

Testing traits in the testbench follow consistent structural patterns:

Core Components

ComponentPurposeExample
Protected hook methodsOverride points for test writersdefineRoutes(), getPackageProviders()
Protected setup methodsCalled by TestCase lifecyclesetUpApplicationRoutes(), registerPackageProviders()
Empty default implementationsAllow optional overridesAll hook methods have empty bodies
Application parameterAccess to application instanceApplicationContract $app

Method Naming Conventions


Sources: src/Concerns/HandlesRoutes.php16-47 src/Concerns/CreatesApplication.php14-58 src/Concerns/HandlesDatabases.php12-55


Built-in Trait Patterns

HandlesRoutes Pattern

The HandlesRoutes trait demonstrates the setup delegation pattern:


Key characteristics:

Sources: src/Concerns/HandlesRoutes.php1-49

CreatesApplication Pattern

The CreatesApplication trait demonstrates the data provider pattern:


Key characteristics:

Sources: src/Concerns/CreatesApplication.php1-60

HandlesDatabases Pattern

The HandlesDatabases trait demonstrates the lifecycle hook pattern:


Key characteristics:

Sources: src/Concerns/HandlesDatabases.php1-56


Creating Custom Traits

Design Principles

When creating custom testing traits, follow these principles:

  1. Single Responsibility: Each trait should handle one testing concern
  2. Empty Defaults: All hook methods should have empty default implementations
  3. Protected Visibility: Use protected for all methods to allow override
  4. No Constructor: Traits should not define constructors
  5. Application Access: Accept ApplicationContract when application context is needed

Trait Structure Template


Integration Points with TestCase

Custom traits can integrate with TestCase at several lifecycle points:

Lifecycle PointIntegration MethodPurpose
Application creationCall from defineEnvironment()Register providers, configure services
Post-creationCall from afterApplicationCreated()Setup routes, initialize features
Pre-testCall from setUp()Per-test initialization
Post-testCall from tearDown()Per-test cleanup
Deferred cleanupCall beforeApplicationDestroyed()Register cleanup callbacks

Sources: src/Concerns/HandlesRoutes.php35-47 src/Concerns/CreatesApplication.php37-58 src/Concerns/HandlesDatabases.php47-55


Example: Building a Mock Server Trait

Here's a complete example of a custom trait for managing mock HTTP servers in tests:


Usage Pattern



Lifecycle Integration Patterns

Pattern 1: Environment Configuration

For traits that need to configure the application during creation:


Sources: src/Concerns/CreatesApplication.php37-58

Pattern 2: Post-Creation Setup

For traits that need to setup after the application is created:


Sources: src/Concerns/HandlesRoutes.php35-47

Pattern 3: Deferred Cleanup

For traits that need guaranteed cleanup:


Sources: src/Concerns/HandlesDatabases.php50


Best Practices

Method Organization

Organize trait methods in the following order:

  1. Hook methods (user override points) - define*(), get*()
  2. Setup methods (called by TestCase) - setUp*(), register*()
  3. Helper methods (public API for tests) - utility methods
  4. Cleanup methods (teardown) - destroy*(), tearDown*()

Naming Conventions

Method TypeNaming PatternExample
Configuration hookdefine{Feature}ConfigdefineQueueConfig()
Data provider hookget{Feature}{Items}getCustomProviders()
Behavior hookdefine{Feature}{Action}defineEventListeners()
Setup methodsetUp{Feature}setUpCustomQueue()
Registration methodregister{Feature}{Items}registerCustomCommands()
Cleanup methodtearDown{Feature}tearDownCustomQueue()
Destruction methoddestroy{Feature}{Items}destroyTestFiles()

Sources: src/Concerns/HandlesRoutes.php19-30 src/Concerns/CreatesApplication.php19-32 src/Concerns/HandlesDatabases.php13-26

Documentation Requirements

Each trait should include:


State Management

Custom traits should:

  1. Avoid instance properties when possible - use application container instead
  2. Initialize properties in setup - never assume properties are initialized
  3. Reset properties in teardown - ensure clean state for next test
  4. Use beforeApplicationDestroyed() for critical cleanup

Reflection Usage

When checking if methods are overridden (like HandlesRoutes does):


This pattern prevents executing empty default implementations when not needed.

Sources: src/Concerns/HandlesRoutes.php43-46


Common Trait Patterns

Queue Testing Trait


Cache Testing Trait


Event Listener Testing Trait



Summary Table

AspectRecommendationExample Reference
NamespaceYourPackage\Testing\Concernssrc/Concerns/HandlesRoutes.php5
Method visibilityprotectedsrc/Concerns/HandlesRoutes.php19
Hook method defaultsEmpty implementationsrc/Concerns/HandlesRoutes.php21
Setup method patternCall hooks, process resultssrc/Concerns/HandlesRoutes.php35-47
Application accessApplicationContract $app parametersrc/Concerns/CreatesApplication.php19
Cleanup patternbeforeApplicationDestroyed()src/Concerns/HandlesDatabases.php50
Method namingdefine*, setUp*, register*, destroy*All trait files
Reflection usageCheck override before executionsrc/Concerns/HandlesRoutes.php43-46

Sources: src/Concerns/HandlesRoutes.php1-49 src/Concerns/CreatesApplication.php1-60 src/Concerns/HandlesDatabases.php1-56