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

This package is not auto-updated.

Last update: 2025-06-15 18:59:29 UTC


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 } } } } } } } }

Swagger example for create user endpoint

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 an Illuminate\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();
}