-
-
Notifications
You must be signed in to change notification settings - Fork 14
feat: add Laravel Testbench-style testing features #344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add Laravel Testbench-style testing features #344
Conversation
Phase 1: defineEnvironment hook - Add defineEnvironment($app) call in refreshApplication() before app boot - Add empty defineEnvironment() method for subclass override - Add DefineEnvironmentTest Phase 2: Attribute contracts - TestingFeature: marker interface - Resolvable: resolve() for meta-attributes (does NOT extend TestingFeature) - Actionable: handle($app, Closure $action) - Invokable: __invoke($app) - BeforeEach/AfterEach: per-test lifecycle hooks - BeforeAll/AfterAll: per-class lifecycle hooks Phase 3: AttributeParser and FeaturesCollection - AttributeParser: parses class/method attributes with inheritance and Resolvable support - FeaturesCollection: collection for deferred attribute callbacks Phase 4.2: HandlesAttributes trait - parseTestMethodAttributes() for executing attribute callbacks
- Static caching for class/method attributes - usesTestingConcern() to check trait usage - usesTestingFeature() for programmatic attribute registration - resolvePhpUnitAttributes() merges all attribute sources - Lifecycle methods: setUpTheTestEnvironmentUsingTestCase, tearDownTheTestEnvironmentUsingTestCase, setUpBeforeClassUsingTestCase, tearDownAfterClassUsingTestCase
Simplified orchestrator for default + attribute flows. Uses inline flag-based memoization instead of Orchestra's once() helper. No annotation/pest support - not needed for Hypervel.
- DefineEnvironment: calls test method with $app - WithConfig: sets config value directly - DefineRoute: calls test method with $router - DefineDatabase: deferred execution, resets RefreshDatabaseState - ResetRefreshDatabaseState: resets database state before/after all tests - WithMigration: loads explicit migration paths - RequiresEnv: skips test if env var missing - Define: meta-attribute resolving to env/db/route attributes
…rastructure - Change Actionable::handle() implementations to return mixed instead of void - Change Invokable::__invoke() implementations to return mixed instead of void - Fix TestingFeature orchestrator closure return type - Add @phpstan-ignore for rescue callback type resolution - Update setUpTheTestEnvironmentUsingTestCase() to execute all attribute types (Invokable, Actionable, BeforeEach)
- Call setUpApplicationRoutes() automatically in afterApplicationCreated - Add reflection check to skip empty web routes group registration - Refactor Sanctum tests to use new testbench pattern (getPackageProviders, defineEnvironment, defineRoutes) - Add tests for route accessibility and routing without defineWebRoutes
…ritance - Mark parseTestMethodAttributes() as @internal to prevent misuse - Add test verifying Define meta-attribute is resolved by AttributeParser - Add test verifying Define meta-attribute is executed through lifecycle - Add tests verifying attributes are inherited from parent TestCase classes
Add proper type hints following existing codebase conventions: - Use `ApplicationContract` alias for contract type hints - Use `Router` type hints for route definition methods - Update all contracts, attributes, traits, and test files This improves type safety while maintaining consistency with the existing codebase pattern where 20+ files use the ApplicationContract alias convention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Ports Laravel Testbench-style package testing infrastructure into Hypervel, including hooks for environment/routes/database setup and PHP 8 attribute-based test configuration.
Changes:
- Added a new attribute-based testing feature system (parser, lifecycle execution, attribute contracts, and built-in attributes like
WithConfig,DefineEnvironment, etc.). - Added Testbench traits for package provider/alias registration, route helpers (including optional web-group wrapping), and database hooks; integrated them into
Hypervel\Testbench\TestCase. - Added/updated tests to validate the new Testbench patterns and attribute/lifecycle behavior (including refactoring Sanctum test setup).
Reviewed changes
Copilot reviewed 37 out of 37 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Testbench/TestCaseTest.php | Adds coverage that the new Testbench TestCase composes the expected traits and applies attributes/hooks. |
| tests/Testbench/Concerns/HandlesRoutesWithoutWebRoutesTest.php | Verifies API routes work when defineWebRoutes() is not overridden. |
| tests/Testbench/Concerns/HandlesRoutesTest.php | Verifies defineRoutes() / defineWebRoutes() are executed and routes are reachable. |
| tests/Testbench/Concerns/CreatesApplicationTest.php | Verifies package providers/aliases hooks work for package testing. |
| tests/Sentry/Features/LogFeatureTest.php | Updates defineEnvironment() signature to the new typed hook. |
| tests/Sanctum/AuthenticateRequestsTest.php | Refactors test setup to use Testbench hooks (getPackageProviders, defineEnvironment, defineRoutes). |
| tests/Foundation/Testing/Concerns/InteractsWithTestCaseTest.php | Adds tests for trait caching and attribute parsing/execution behavior. |
| tests/Foundation/Testing/Concerns/HandlesAttributesTest.php | Adds coverage for parsing/executing method attributes via the concern. |
| tests/Foundation/Testing/Concerns/DefineEnvironmentTest.php | Verifies defineEnvironment() hook is invoked during setup and can mutate config. |
| tests/Foundation/Testing/Concerns/AttributeInheritanceTest.php | Verifies attribute inheritance from parent test case classes. |
| tests/Foundation/Testing/Attributes/AttributesTest.php | Adds coverage for attribute contracts/targets and attribute behaviors. |
| src/testbench/src/TestCase.php | Integrates new Testbench traits and coroutine-aware lifecycle execution into the base Testbench test case. |
| src/testbench/src/Concerns/HandlesRoutes.php | Adds defineRoutes / defineWebRoutes hooks and automatic application route setup. |
| src/testbench/src/Concerns/HandlesDatabases.php | Adds migration/seeder hook structure and a setUpDatabaseRequirements() helper. |
| src/testbench/src/Concerns/CreatesApplication.php | Adds package provider/alias hook APIs and registration helpers. |
| src/foundation/src/Testing/Features/TestingFeature.php | Adds an orchestrator intended to coordinate default vs attribute-based feature execution. |
| src/foundation/src/Testing/Features/FeaturesCollection.php | Adds a collection type to manage and execute deferred feature callbacks. |
| src/foundation/src/Testing/Contracts/Attributes/TestingFeature.php | Adds a marker interface for test feature attributes. |
| src/foundation/src/Testing/Contracts/Attributes/Resolvable.php | Adds a contract for meta-attributes that resolve into concrete attributes. |
| src/foundation/src/Testing/Contracts/Attributes/Invokable.php | Adds a contract for directly invokable attributes (e.g., WithConfig). |
| src/foundation/src/Testing/Contracts/Attributes/BeforeEach.php | Adds lifecycle contract for “before each test” attributes. |
| src/foundation/src/Testing/Contracts/Attributes/BeforeAll.php | Adds lifecycle contract for “before all tests in class” attributes. |
| src/foundation/src/Testing/Contracts/Attributes/AfterEach.php | Adds lifecycle contract for “after each test” attributes. |
| src/foundation/src/Testing/Contracts/Attributes/AfterAll.php | Adds lifecycle contract for “after all tests in class” attributes. |
| src/foundation/src/Testing/Contracts/Attributes/Actionable.php | Adds contract for attributes that dispatch method execution via a callback. |
| src/foundation/src/Testing/Concerns/InteractsWithTestCase.php | Adds attribute caching plus lifecycle execution (Before/After Each/All) for PHPUnit test cases. |
| src/foundation/src/Testing/Concerns/InteractsWithContainer.php | Adds and invokes the defineEnvironment() hook during application refresh. |
| src/foundation/src/Testing/Concerns/HandlesAttributes.php | Adds an internal API for parsing/executing attributes of a specific type. |
| src/foundation/src/Testing/Attributes/WithMigration.php | Adds attribute to register migration paths via the Migrator. |
| src/foundation/src/Testing/Attributes/WithConfig.php | Adds attribute to set config key/value pairs. |
| src/foundation/src/Testing/Attributes/ResetRefreshDatabaseState.php | Adds attribute to reset RefreshDatabaseState before/after a test class. |
| src/foundation/src/Testing/Attributes/RequiresEnv.php | Adds attribute to skip tests when required environment variables are missing. |
| src/foundation/src/Testing/Attributes/DefineRoute.php | Adds attribute to invoke a route-definition method with the Router. |
| src/foundation/src/Testing/Attributes/DefineEnvironment.php | Adds attribute to invoke an environment-definition method with the app container. |
| src/foundation/src/Testing/Attributes/DefineDatabase.php | Adds attribute to invoke database setup methods with deferred execution support. |
| src/foundation/src/Testing/Attributes/Define.php | Adds meta-attribute resolving shorthand (env/db/route) to concrete attributes. |
| src/foundation/src/Testing/AttributeParser.php | Adds parser to collect (and resolve) testing-related attributes from classes/methods. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix usesTestingFeature test to use TARGET_METHOD flag to avoid class-level feature persistence affecting other tests - Fix PHPDoc return type in HandlesAttributes to correctly reflect Collection<Collection> instead of Collection<array> - Fix deferred Actionable attributes (like DefineDatabase with defer:true) by capturing and executing returned closures in setUpTheTestEnvironmentUsingTestCase - Add tests for deferred attribute execution and return type validation
This class was ported from Orchestra Testbench but never integrated. It was dead code that was never imported or called anywhere.
Summary
This PR ports Laravel Orchestral Testbench's testing infrastructure to Hypervel, bringing familiar testing patterns and PHP 8 attribute-based test configuration to Hypervel.
Key Features Ported from Laravel Testbench
defineEnvironment()hook - Pre-boot application configuration, matching Laravel'sdefineEnvironment()patterngetPackageProviders()andgetPackageAliases()methods for package testingdefineRoutes()anddefineWebRoutes()with automatic web middleware group wrappingdefineDatabaseMigrations(),destroyDatabaseMigrations(),defineDatabaseSeeders()Testing Attributes (Following Laravel Testbench Patterns)
#[WithConfig('key', 'value')]#[DefineEnvironment('methodName')]$appfor environment setup#[DefineRoute('methodName')]$routerfor route definition#[DefineDatabase('methodName')]#[WithMigration('path')]#[RequiresEnv('VAR')]#[ResetRefreshDatabaseState]#[Define('group', 'method')]Lifecycle Hooks (Matching Laravel Testbench)
BeforeAll/AfterAll- Class-level lifecycle (static, runs once per test class)BeforeEach/AfterEach- Test-level lifecycle (runs for each test method)Invokable- Direct invocation with app instanceActionable- Method delegation with closure callbackHypervel-Specific Adaptations
While following Laravel Testbench patterns closely, this implementation includes Hypervel-specific adaptations:
BeforeEach/AfterEachattributes execute insiderunInCoroutine(), matching wheresetUpTraits()runs in Foundation TestCase$router->group()signaturesetUpApplicationRoutes()is called automatically inafterApplicationCreated, so routes defined viadefineRoutes()are available without manual setupRouteFileCollectorwhendefineWebRoutes()isn't overriddenExample Usage
Files Changed
New Files (28)
Foundation Contracts (
src/foundation/src/Testing/Contracts/Attributes/):TestingFeature.php,Resolvable.php,Actionable.php,Invokable.phpBeforeEach.php,AfterEach.php,BeforeAll.php,AfterAll.phpFoundation Attributes (
src/foundation/src/Testing/Attributes/):DefineEnvironment.php,WithConfig.php,DefineRoute.php,DefineDatabase.phpWithMigration.php,RequiresEnv.php,ResetRefreshDatabaseState.php,Define.phpFoundation Infrastructure (
src/foundation/src/Testing/):AttributeParser.php- Parses class/method attributes with Resolvable supportConcerns/HandlesAttributes.php- Attribute parsing traitConcerns/InteractsWithTestCase.php- Caching and lifecycle executionFeatures/TestingFeature.php- Orchestrator for default + attribute flowsFeatures/FeaturesCollection.php- Collection for deferred callbacksTestbench Traits (
src/testbench/src/Concerns/):CreatesApplication.php- Package providers/aliasesHandlesRoutes.php- Route definition helpersHandlesDatabases.php- Database migration helpersTests (7 test files with comprehensive coverage)
Modified Files (3)
src/foundation/src/Testing/Concerns/InteractsWithContainer.php- AddeddefineEnvironment()hooksrc/testbench/src/TestCase.php- Integrated new traits with coroutine-aware lifecycletests/Sanctum/AuthenticateRequestsTest.php- Refactored to use new testbench pattern (getPackageProviders,defineEnvironment,defineRoutes)