n4m-ward / laravel-perry
There is no license information available for the latest version (0.0.7) of this package.
0.0.7
2025-06-15 18:54 UTC
Requires
- ext-yaml: *
Requires (Dev)
- orchestra/testbench: ^9.8
- phpunit/phpunit: ^11.5
README
Summary
Setup
Creating Tests
Usage examples
Doing assertions
Setup
Install the library:
composer require n4m-ward/laravel-perry --dev
Run the following command once to generate the configuration files
./vendor/bin/perry
After running the command above, two files will be created
- A
perry.json
file containing the following data:
{ "testsFolderPath": "/tests/Perry", "testExecutorPath": "/vendor/bin/phpunit", "swaggerOutputPath": "/perry_output/swagger", "cacheOutputPath": "/perry_output/cache" }
- A
BaseTestCase.php
file that you will extend in your e2e tests - The
BaseTestCase
will be created in the following path:/tests/Perry/BaseTestCase.php
- You can change the path of this file if you want, or use your own
BaseTestCase
<?php namespace Tests\Perry; use Perry\Attributes\Info; use Perry\Attributes\Server; use Perry\Attributes\Servers; use Perry\PerryHttp\PerryHttpRequest; use Illuminate\Foundation\Testing\TestCase as LaravelTestCase; #[Servers( new Server(description: 'Example server local', url: 'http://localhost:8000') )] #[Info( version: '1.0.0', title: 'Example server title', description: 'Example server description', contactEmail: 'test@example.com', termsOfService: 'https://example.com/terms-of-service', // optional parameter externalDocs: new ExternalDocs( // optional parameter url: 'https://example.com/external-docs', description: 'Find more info here', ), )] abstract class BaseTestCase extends LaravelTestCase { use PerryHttpRequest; }
Creating Tests
-
First, create a class extending the
BaseTestCase
created above -
For example, an
UserControllerTest
-
Then let's create our first e2e test
public function test_shouldCreateUser() { $this ->perryHttp() ->withBody([ 'name' => 'John Doe', 'age' => 25, 'email' => 'john@doe.com', 'password' => 'password', ]) ->post('/user') ->assertJson(['success' => true]) ->assertStatus(Response::HTTP_CREATED); $this->assertDatabaseHas('users', [ 'name' => 'John Doe', 'age' => 25, 'email' => 'john@doe.com', ]); }
- Then run the following command
./vendor/bin/perry
- So, the following documentation will be created on the path
perry_output/swagger/output.yaml
openapi: 3.0.0 servers: - { description: 'Server Local', url: 'http://localhost:8080' } info: version: 1.0.0 title: 'Example server title' description: 'Example server description' contact: { email: test@example.com } termsOfService: 'https://example.com/terms-of-service' externalDocs: description: 'Find more info here' url: 'https://example.com/external-docs' paths: /user: { post: { summary: 'should create user', description: 'should create user', operationId: test_shouldCreateUser, responses: { 201: { description: '201', content: { application/json: { schema: { type: object, properties: { success: { type: boolean, example: true } } } } } } }, requestBody: { description: 'should create user', content: { application/json: { schema: { type: object, properties: { name: { type: string, example: 'John Doe' }, age: { type: integer, format: int32, example: 25 }, email: { type: string, example: john@doe.com }, password: { type: string, example: password } } } } } } } }
Usage examples
Request using header
public function test_exampleWithHeaders(): void { $this ->perryHttp() ->withHeaders([ 'Authorization' => 'Bearer token', ]) ->get('/api/example'); }
Request using body
public function test_exampleWithHeaders(): void { $this ->perryHttp() ->withBody([ 'foo' => 'bar', ]) ->post('/api/example'); }
Request using body and headers
public function test_exampleWithHeadersAndBody(): void { $this ->perryHttp() ->withHeaders([ 'Authorization' => 'Bearer token', ]) ->withBody([ 'foo' => 'bar', ]) ->post('/api/example'); }
Available http methods
public function test_get(): void { $this->perryHttp()->get('/api/example/123'); } public function test_post(): void { $this ->perryHttp() ->withBody(['foo' => 'bar']) ->post('/api/example'); } public function test_put(): void { $this ->perryHttp() ->withBody(['foo' => 'bar']) ->put('/api/example/123'); } public function test_patch(): void { $this ->perryHttp() ->withBody(['foo' => 'bar']) ->patch('/api/example/123'); } public function test_delete(): void { $this->perryHttp()->delete('/api/example/123'); }
Using securityScheme
First, on your TestCase or your BaseTestCase, add the following attribute
#[SecurityScheme(securityScheme: 'BearerToken', type: 'http', scheme: 'bearer')] class SomeTest extends BaseTestCase {}
Then, on your test method, add the following attribute
#[UseSecurityScheme('BearerToken')] public function test_shouldCreateUser(): void { }
Using tags
First add the Tag
attribute on your TestCase or your BaseTestCase
#[\Perry\Attributes\Tag\Tag(name: 'User', description: "User related endpoints")] class SomeTest extends BaseTestCase {}
If you want, you can add the externalDocs to your tag
#[\Perry\Attributes\Tag\Tag( name: 'User', description: "User related endpoints" externalDocs: new \Perry\Attributes\ExternalDocs( url: 'https://example.com/external-docs', description: 'Find more info here', )] class SomeTest extends BaseTestCase {}
Then, on your test method, add the UsingTag
attribute
#[\Perry\Attributes\Tag\UsingTag('User')] public function test_shouldCreateUser(): void { }
Doing assertions
- The method
perryHttp()
will return anIlluminate\Testing\TestResponse
- With the
TestResponse
, we can do some assertions as we can see bellow - You can see all available assertions for
TestResponse
Clicking here
public function test_shouldMakeHttpRequest_AndValidateResponseBody(): void { $this ->perryHttp() ->get('/user/123') ->assertJson([ 'name' => 'John Doe', 'age' => 25, 'email' => 'john@doe.com', 'password' => 'password', ]) ->assertStatus(Response::HTTP_OK); } public function test_shouldDoHttpRequest_AndValidateIsUnauthorized(): void { $this ->perryHttp() ->delete('/user/123') ->assertJson([ 'message' => 'Unauthorized', ]) ->assertUnauthorized(); }