midnightsuyama / laravel-kahlan4
Kahlan specs suite for Laravel
Installs: 14 658
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 1
Forks: 2
Open Issues: 0
pkg:composer/midnightsuyama/laravel-kahlan4
Requires
- php: ^7.2 || ^8.0
- kahlan/kahlan: ^4.6 || ^5.0
- laravel/framework: ^6.0 || ^7.0 || ^8.0 || ^9.0
This package is not auto-updated.
Last update: 2025-12-11 08:53:38 UTC
README
Kahlan specs suite for Laravel
Features
- Support Laravel test methods
- Support Laravel test traits
- Support Laravel test assertions
Installation
$ composer require --dev midnightsuyama/laravel-kahlan4
Usage
Add this line to your kahlan-config.php file (create it if necessary):
<?php LaravelKahlan4\Config::bootstrap($this);
and
$ ./vendor/bin/kahlan
Example
<?php // spec/User.spec.php describe('User', function() { it('has a name "example"', function() { $user = factory(App\User::class)->make(['name' => 'xample']); expect($user['name'])->toEqual('example'); }); });
$ ./vendor/bin/kahlan
_ _
/\ /\__ _| |__ | | __ _ _ __
/ //_/ _` | '_ \| |/ _` | '_ \
/ __ \ (_| | | | | | (_| | | | |
\/ \/\__,_|_| |_|_|\__,_|_| |_|
The PHP Test Framework for Freedom, Truth and Justice.
src directory :
spec directory : /spec
F 1 / 1 (100%)
User
✖ it has a name "example"
expect->toEqual() failed in `./spec/User.spec.php` line 7
It expect actual to be equal to expected (==).
actual:
(string) "xample"
expected:
(string) "example"
Expectations : 1 Executed
Specifications : 0 Pending, 0 Excluded, 0 Skipped
Passed 0 of 1 FAIL (FAILURE: 1) in 0.817 seconds (using 20MB)
Method
$response = $this->laravel->get('/');
$this->laravel is an instance of Illuminate\Foundation\Testing\TestCase subclass. It can call test methods of Illuminate\Foundation\Testing\Concerns.
Trait
use Illuminate\Foundation\Testing\RefreshDatabase; describe('User table', function() { beforeAll(function() { $this->laravel->useTrait(RefreshDatabase::class); }); it('has no records', function() { $count = App\User::count(); expect($count)->toEqual(0); }); });
Call $this->laravel->useTrait() in beforeAll, if you want to use test traits. That trait is set before beforeEach is called.
Support traits
- Illuminate\Foundation\Testing\RefreshDatabase
- Illuminate\Foundation\Testing\DatabaseMigrations
- Illuminate\Foundation\Testing\DatabaseTransactions
- Illuminate\Foundation\Testing\WithoutMiddleware
- Illuminate\Foundation\Testing\WithoutEvents
- Illuminate\Foundation\Testing\WithFaker
Matcher
Provied custom matchers. toPass* matcher is paired with assert* assertion by Laravel.
Response
describe('Response', function() { it('has a 200 status code', function() { $response = $this->laravel->get('/'); expect($response)->toPassStatus(200); }); });
| Matcher | Description |
|---|---|
| toPassSuccessful() | The response has a successful status code. |
| toPassOk() | The response has a 200 status code. |
| toPassNotFound() | The response has a not found status code. |
| toPassForbidden() | The response has a forbidden status code. |
| toPassUnauthorized() | The response has an unauthorized status code. |
| toPassCreated() | The response has a 201 status code. |
| toPassNoContent($status = 204) | The response has the given status code and no content. |
| toPassStatus($status) | The response has the given status code. |
| toPassRedirect($uri = null) | The response is redirecting to a given URI. |
| toPassHeader($headerName, $value = null) | The response contains the given header and equals the optional value. |
| toPassHeaderMissing($headerName) | The response does not contains the given header. |
| toPassLocation($uri) | The current location header matches the given URI. |
| toPassPlainCookie($cookieName, $value = null) | The response contains the given cookie and equals the optional value. |
| toPassCookie($cookieName, $value = null, $encrypted = true, $unserialize = false) | The response contains the given cookie and equals the optional value. |
| toPassCookieExpired($cookieName) | The response contains the given cookie and is expired. |
| toPassCookieNotExpired($cookieName) | The response contains the given cookie and is not expired. |
| toPassCookieMissing($cookieName) | The response does not contains the given cookie. |
| toPassSee($value) | The given string is contained within the response. |
| toPassSeeInOrder(array $values) | The given strings are contained in order within the response. |
| toPassSeeText($value) | The given string is contained within the response text. |
| toPassSeeTextInOrder(array $values) | The given strings are contained in order within the response text. |
| toPassDontSee($value) | The given string is not contained within the response. |
| toPassDontSeeText($value) | The given string is not contained within the response text. |
| toPassJson(array $data, $strict = false) | The response is a superset of the given JSON. |
| toPassExactJson(array $data) | The response has the exact given JSON. |
| toPassJsonFragment(array $data) | The response contains the given JSON fragment. |
| toPassJsonMissing(array $data, $exact = false) | The response does not contain the given JSON fragment. |
| toPassJsonMissingExact(array $data) | The response does not contain the exact JSON fragment. |
| toPassJsonPath($path, $expect, $strict = false) | The expected value exists at the given path in the response. |
| toPassJsonStructure(array $structure = null, $responseData = null) | The response has a given JSON structure. |
| toPassJsonCount(int $count, $key = null) | The response JSON has the expected count of items at the given key. |
| toPassJsonValidationErrors($errors) | The response has the given JSON validation errors. |
| toPassJsonMissingValidationErrors($keys = null) | The response has no JSON validation errors for the given keys. |
| toPassViewIs($value) | The response view equals the given value. |
| toPassViewHas($key, $value = null) | The response view has a given piece of bound data. |
| toPassViewHasAll(array $bindings) | The response view has a given list of bound data. |
| toPassViewMissing($key) | The response view is missing a piece of bound data. |
| toPassSessionHas($key, $value = null) | The session has a given value. |
| toPassSessionHasAll(array $bindings) | The session has a given list of values. |
| toPassSessionHasInput($key, $value = null) | The session has a given value in the flashed input array. |
| toPassSessionHasErrors($keys = [], $format = null, $errorBag = 'default') | The session has the given errors. |
| toPassSessionDoesntHaveErrors($keys = [], $format = null, $errorBag = 'default') | The session is missing the given errors. |
| toPassSessionHasNoErrors() | The session has no errors. |
| toPassSessionHasErrorsIn($errorBag, $keys = [], $format = null) | The session has the given errors. |
| toPassSessionMissing($key) | The session does not have a given key. |
Authentication
describe('User', function() { it('is authenticated', function() { $user = factory(App\User::class)->make(); $this->laravel->actingAs($user); expect($this->laravel)->toPassAuthenticated(); }); });
| Matcher | Description |
|---|---|
| toPassAuthenticated($guard = null) | The user is authenticated. |
| toPassGuest($guard = null) | The user is not authenticated. |
| toPassAuthenticatedAs($user, $guard = null) | The user is authenticated as the given user. |
| toPassCredentials(array $credentials, $guard = null) | The given credentials are valid. |
| toPassInvalidCredentials(array $credentials, $guard = null) | The given credentials are invalid. |
Database
describe('User table', function() { it('has records', function() { $user = factory(App\User::class)->create(); expect($this->laravel)->toPassDatabaseHas('users', ['email' => $user['email']]); }); });
| Matcher | Description |
|---|---|
| toPassDatabaseHas($table, array $data, $connection = null) | A given where condition exists in the database. |
| toPassDatabaseMissing($table, array $data, $connection = null) | A given where condition does not exist in the database. |
| toPassSoftDeleted($table, array $data = [], $connection = null) | The given record has been deleted. |
Notification
use Illuminate\Auth\Notifications\VerifyEmail; use Illuminate\Support\Facades\Notification; describe('User', function() { it('is notified', function() { $notification = Notification::fake(); expect($notification)->toPassNothingSent(); $user = factory(App\User::class)->create(); $user->notify(new VerifyEmail); expect($notification)->toPassSentTo($user, VerifyEmail::class); }); });
| Matcher | Description |
|---|---|
| toPassNothingSent() | No notifications were sent. |
| toPassSentTo($notifiable, $notification, $callback = null) | The given notification was sent based on a truth-test callback. |
| toPassNotSentTo($notifiable, $notification, $callback = null) | The given notification was not sent based on a truth-test callback. |
| toPassSentToTimes($notifiable, $notification, $times = 1) | The given notification was sent a number of times. |
| toPassTimesSent($expectedCount, $notification) | The total amount of times a notification was sent. |
Test
$ cd test-project
$ composer install
$ touch database/database.sqlite
$ php artisan migrate --env=testing
$ ./vendor/bin/kahlan
_ _
/\ /\__ _| |__ | | __ _ _ __
/ //_/ _` | '_ \| |/ _` | '_ \
/ __ \ (_| | | | | | (_| | | | |
\/ \/\__,_|_| |_|_|\__,_|_| |_|
The PHP Test Framework for Freedom, Truth and Justice.
src directory :
spec directory : /test-project/spec
............................................................. 61 / 61 (100%)
Expectations : 61 Executed
Specifications : 0 Pending, 0 Excluded, 0 Skipped
Passed 61 of 61 PASS in 7.760 seconds (using 37MB)
License
Licensed using the MIT license.
Acknowledgments
Inspired by sofa/laravel-kahlan.