xentral / laravel-testing
A laravel package which provides workflows and tooling around testing
Requires
- php: ^8.2
- behat/behat: ^3.14
- driftingly/rector-laravel: ^2.0
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- illuminate/validation: ^10.0|^11.0|^12.0
- jonathanjfshaw/phpunitbehat: ^0.21.0
- kirschbaum-development/laravel-openapi-validator: ^1.0
- laravel/prompts: ^0.1.9
- phpunit/phpunit: ^10.5 || ^11.5
- qase/phpunit-reporter: ^2.1
- rector/rector: ^2.1
Requires (Dev)
- larastan/larastan: ^3.5
- laravel/boost: ^1.0
- laravel/pint: ^1.8
- nunomaduro/collision: ^8.8
- orchestra/pest-plugin-testbench: ^3.2
- orchestra/testbench: ^9.14
- pestphp/pest: ^3.7
- pestphp/pest-plugin-type-coverage: ^3.6
README
This package provides comprehensive testing tools for Laravel applications, including OpenAPI validation, Behat feature testing, and Qase test reporting integration.
Installation
You can install the package via composer.
composer --dev require xentral/laravel-testing
Usage
OpenAPI Validation
Automatically validate your API responses against OpenAPI schemas in your tests.
The Schema file will be determined in the following order:
- Using the
schemaFilePath
property (if notnull
) - Using the
SchemaFile
attribute - Using the configured
testing.openapi.default_schema
config value
Relative paths will be auto prefixed with the project base path (by default)
Basic example with PHPUnit:
<?php #[SchemaFile('api-schema.yml')] class MyEndpointTest extendsTestCase { use \Xentral\LaravelTesting\OpenApi\ValidatesOpenApiSpec; public function test_api_returns_valid_response() { $response = $this->getJson('/api/users')->assertOk(); } }
Basic example with Pest: Pest does not support attributes (at least i couldn't figure it out). You need to use beforeEach to set the schema file path.
<?php uses(Xentral\LaravelTesting\OpenApi\ValidatesOpenApiSpec::class); beforeEach(function () { $this->schemaFilePath('api-schema.yml'); }); test('API returns valid response', function () { $response = $this->getJson('/api/users')->assertOk(); // Automatically validates against OpenAPI schema });
Behat Feature Testing
Write behavior-driven tests using Gherkin syntax alongside your PHPUnit tests. (Does not work with Pest yet)
Basic Usage:
// tests/Feature/MyEndpointTest.php <?php class MyEndpointTest extends TestCase { use HasBehatFeature; #[DataProvider('featureProvider')] public function test_behat_scenario($scenario, $feature) { $this->executeScenario($scenario, $feature); } }
Feature File:
# tests/Feature/MyEndpointTest.feature Feature: Basic example feature Scenario: example endpoint scenario Given There are 5 testModels When I send a GET request to path /api/v1/test-models Then the response status code should be 200 And the response should contain the following properties | path | value | | data | ~count~5 |
The example above will automatically load the feature file with the same name as the test class with .feature
extension.
This is our preferred behavior, but you can go another way by specifying the via the FeatureFile
attribute on the
class:
// tests/Feature/MyEndpointTest.php <?php #[FeatureFile(__DIR__.'/custom-feature.feature')] class MyEndpointTest extends TestCase { use HasBehatFeature; #[DataProvider('featureProvider')] public function test_behat_scenario($scenario, $feature) { $this->executeScenario($scenario, $feature); } }
Interactive Matcher Discovery
The package includes a powerful interactive command to explore and search available Behat matchers:
php artisan xentral:list-behat-matchers
This command provides an interactive search interface where you can:
- Type to search through matcher patterns and descriptions in real-time
- Browse available matchers with their examples
- View detailed information about each matcher including capture groups
For non-interactive usage (useful in CI/CD):
php artisan xentral:list-behat-matchers --non-interactive
Adding Examples to Custom Matchers
Document your custom Behat matchers with examples using the #[Example]
attribute:
<?php use Xentral\LaravelTesting\Behat\Attributes\Example; class MyCustomMatchers { #[Given('/^I send (a|an invalid|a non-API) ([^\s]+) request to path ([^\s]+)(?:\s+(.+))?$/i')] #[Example('I send a GET request to path /api/users', ['a', 'GET', '/api/users'])] #[Example('I send a POST request to path /api/users with payload', ['a', 'POST', '/api/users', 'with payload'])] public function iSendARequest($type, $method, $path, $modifiers = null) { // Implementation } }
The Example
attribute accepts:
stepText
: The exact step text that should match the patternmatches
(optional): Array of expected capture groups from the regexdata
(optional): Additional metadata for the example
Testing Your Matchers
Ensure your custom matchers work correctly by adding tests using the BehatMatcherChecker
:
<?php use Xentral\LaravelTesting\Behat\BehatMatcherChecker; use Xentral\LaravelTesting\Behat\BehatMatcherFinder; use Xentral\LaravelTesting\Behat\Dto\BehatMatcher; test('all example attributes match their declared matchers', function (BehatMatcher $matcher) { BehatMatcherChecker::check($matcher); })->with( fn () => array_map( fn (BehatMatcher $matcher) => [$matcher], BehatMatcherFinder::find('path/to/your/matchers'), ) );
This test will:
- Find all matchers in the specified directory
- Validate that each
#[Example]
attribute matches its corresponding matcher pattern - Verify that capture groups are correctly extracted
- Ensure regex patterns are valid
Qase Test Run Reporter
Integrate with Qase.io for comprehensive test reporting and management.
Mark a PHPUnit test class with the \Qase\PHPUnitReporter\Attributes\Suite
attribute, then it will be automatically
reported to Qase.io when it is executed in testops
mode.
PHPUnit Configuration:
<!-- phpunit.xml --> <phpunit> <extensions> <bootstrap class="Xentral\LaravelTesting\Qase\XentralQaseExtension"/> </extensions> </phpunit>
More information can be found in the Qase PHPUnit Reporter qase/phpunit-reporter.
Testing
composer test
Contributing
Ideas/Roadmap
Here are some ideas for future development:
- Add support for Behat in Pest.
- Add Support for Qase Test Suite in Pest
- Add support for Outlines in the BehatDumper
- Extend Qase test cases with complete behat scenario information if given
Please see CONTRIBUTING for details.
Security
If you discover any security related issues, please email manuel@christlieb.eu instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.