Testing your OpenApi documentation and your code easily.

Related tags

Miscellaneous Raven
Overview

Raven - How to test your API documentation and behavior.

Scrutinizer Code Quality Code Coverage

Latest Stable Version License

This library was written to allow testing OpenAPI documentation easily. It also allows verifying that your code implementation is compatible with that documentation.

Why creating such tool ?

We work a lot on API related projects. Sometimes we create API, sometimes we consume them. The OpenAPI description format is now well known and used in a lot of different contexts.

Our concern is that it's hard to ensure that the written documentation is representing the current API behavior. We wanted to track the implementation difference between the doc and the code.

We searched the ecosystem and found that it exists different tools to mock APIs or to perform requests to them. However we can't find a tool that allows performing HTTP requests that use fixtures and are able to perform specific validation on the responses.

So we started working on Raven!

It relies on PSRs to be easily integrated in any project and is composed of two different parts:

  • An HTTP request factory to define the input,
  • An executor that'll be responsible to actually validate Requests and Responses.

Raven, isn't it a bird ?

Nope, we use here the human name of the X-Men character Mystique. She's able to transform and adapt to any situation which is that tool goal. We need to adapt to any API to trigger valid requests and analyze responses.

Install it

Using Composer:

composer require chstudio/raven

To use Raven you might need to also install:

Of course you can also write your own. The only constraint is to be compatible with PSRs interfaces.

Usage

Execute Request / Response validation

This library defines its own interfaces for request validation. It comes with an adapter to the league/openapi-psr7-validator package which define a complete validation logic.

<?php

use CHStudio\Raven\Bridge\LeagueOpenAPIValidation\Factory;
use CHStudio\Raven\Validator\Expectation\ExpectationCollection;

// Load OpenAPI description file
$factory = Factory::fromYamlFile('specific/path/to/openapi.yaml');

$executor = new Executor(
    /** Your own HTTP client implementation */,
    $factory->getRequestValidator(),
    $factory->getResponseValidator()
);

$executor->execute($request);

Generate requests easily based on configuration

Writing RequestInterface objects manually might not be the simplest way to define your test cases. We created a RequestFactory to help building those objects. It rely on PSR17 HTTP factories.

Here is an example which use the nyholm/psr7.

<?php

use CHStudio\Raven\Http\Factory\RequestFactory;
use Nyholm\Psr7\Factory\Psr17Factory;

$psrFactory = new Psr17Factory();
$requestFactory = new RequestFactory($psrFactory, $psrFactory);

$request = $requestFactory->fromArray([
    'uri' => 'http://myhost.com/api/users/me',
    'method' => 'POST',
    'headers' => [
        'Content-Type' => 'application/json',
        'Authorization' => 'Bearer token'
    ],
    'body' => '{"aSimple": "objectDefinition", "yep": true}'
]);

If the body is given as an array, it will be encoded based on the Content-Type header:

  • application/json, no header or unsupported header will be transformed to JSON,
  • multipart/form-data, will use http_build_query.

Enrich your request body with resolver

Most of the time having static request bodies will not be powerful enough. We need identifiers and other details extracted from our fixtures. A specific layer can be added around the RequestFactory to resolve body dynamically.

You can combine different Resolver and let the configured body pass through all the methods and be enriched. This library come with a specific Faker resolver to generate data easily with providers (see Faker doc).

You can build your own resolvers using the ValueResolverInterface.

<?php

use CHStudio\Raven\Http\Factory\Resolver\ArrayValueResolver;
use CHStudio\Raven\Http\Factory\Resolver\FakerValueResolver;
use CHStudio\Raven\Http\Factory\Resolver\PassThroughValueResolver;

//Configure your own faker generator, maybe with some `addProvider` calls.
$generator = \Faker\Factory::create();

//Configure specific resolver logic.
$valueResolver = new ArrayValueResolver(
    new FakerValueResolver(
        $generator,
        new PassThroughValueResolver()
    )
);

//Apply it on the request factory built in the previous section.
$requestFactory = new RequestUriParametersResolver(
    $valueResolver,
    new RequestBodyResolver(
        $valueResolver,
        $requestFactory
    )
);

$request = $requestFactory->fromArray([
    'uri' => [
        'base' => 'http://myhost.com/api/users/{id}',
        'parameters' => [
            //This value will be resolved by `RequestUriParametersResolver`
            '{id}' => '<userId()>'
        ]
    ],
    'method' => 'POST',
    'body' => [
        'scalar' => [
            'bool' => true,
            'int' => 23456,
            'float' => 18.06
        ],
        //Built in Faker provider resolved by `RequestBodyResolver`
        'faker' => [
            'name' => '<name()>',
            'creationDate' => '<date("Y-m-d")>',
        ]
        //Specific provider to query database
        'institution' => '<institutionId("Massachusetts General Hospital")>'
    ]
]);

/**
 * This will generate an URL like this: http://myhost.com/api/users/a5098711-b6b2-4acb-96ea-f8baf496c700
 *
 * This will generate the following body:
 *
 * {
 *     "scalar": {
 *         "bool": true,
 *         "int": 23456,
 *         "float": 18.06
 *     },
 *     "faker": {
 *         "name": "John Doe",
 *         "creationDate": "2022-10-03"
 *     },
 *     "institution": "bf91c434-dcf3-3a4c-b49a-12e0944ef1e2"
 * }
 */

Custom expectations

Validating that the request and the response are respecting the documentation is nice but we might need to add some user defined expectations. Will this request trigger a 401 response ? Is the body containing the correct value ?

Expectation can be built using request definition data. Based on some properties, they will be added dynamically. The expectation collection can be passed to the Executor::execute method.

If one of the expectation fails, the response validation will fail and you'll get the details through a ExpectationFailedException error.

<?php

use CHStudio\Raven\Validator\Expectation\ExpectationFactory;

$requestData = [
    'uri' => 'http://myhost.com/api/users/me',
    'method' => 'GET',
    'statusCode' => 403
];

$expectations = (new ExpectationFactory())->fromArray($requestData);
$request = $requestFactory->fromArray($requestData);

$executor->execute($request, $expectations);

This library come with built in expectations: StatusCode. You can easily build your own using the ResponseExpectationInterface.

License

This package is released under the Apache-2 license.

Contribute

If you wish to contribute to the project, please read the CONTRIBUTING notes.

Comments
  • Allow oldest versions for some lib

    Allow oldest versions for some lib

    Is your feature request related to a problem? Please describe. I'm always frustrated when I try to install Raven and my others dependency are not compatible

    Describe the solution you'd like The library should be compatible with league/openapi-psr7-validator:0.17.0 psr/log:^1|^2

    Describe alternatives you've considered Allow psr/log:^1|^2

    Additional context My project uses graylog2/gelf-php which is compatible with psr/log: ^1|^2. So, when I want to install Raven with composer, it makes errors because Raven needs psr/log:3

    enhancement 
    opened by emyrtille 1
  • Capture invalid query arguments error arised from LeagueOpenApiValidator

    Capture invalid query arguments error arised from LeagueOpenApiValidator

    Before the missing required arguments were silented because the inner LeagueOpenApiValidator exception wasn't mapped correctly.

    Now, whenever an "InvalidQueryArgs" error arise, we keep it instead of the final leaf of the exception chain.

    opened by shulard 0
  • Better capture

    Better capture "invalid body" errors in the Request or the Response.

    Is your feature request related to a problem? Please describe.

    Today it's really hard to find where an invalid body error occurs. We must be able to expose the corresponding body to diagnose the issue. Today we got a simple:

    Something went wrong: JSON parsing failed with "Syntax error" for Request
    

    Describe the solution you'd like

    Attaching the message which has a failed body to the exception so we might use it to display relevant details to the user.

    enhancement 
    opened by shulard 0
  • Faker parameter resolution: Allow to resolve nested parameter definition

    Faker parameter resolution: Allow to resolve nested parameter definition

    Describe the bug

    When you define a "faker resolvable" property, you can't have more than one level of faker resolution.

    For example with somethink link that: '<storageIdFromAet(<dicomAet("WS-PARIS")>)>', dicomAet will not be called.

    To Reproduce

    A sample YAML configuration to generate a request with that kind of issue:

    testThatCase:
      uri:
        base: /api/uri?parameter={storage}
        parameters:
          '{storage}': '<storageIdFromAet(<dicomAet("WS-PARIS")>)>'
    

    Expected behavior

    We might allow to resolve nested faker definition.

    bug good first issue 
    opened by shulard 0
  • Allow to execute sequences of Requests for a single text execution.

    Allow to execute sequences of Requests for a single text execution.

    Sometimes when working with APIs, you want to perform a sequence of calls then analyze the result. It can be useful to create resources before verifying the API can access it…

    The logic will be the same, every request will be tested, with expectations but the goal is just to run a sequence of calls synchronously.

    enhancement 
    opened by shulard 0
  • Allow to define new Resolver and new Expectation easily.

    Allow to define new Resolver and new Expectation easily.

    Today Raven defines Resolver objects that will be used to enrich the Request body and parameters.

    There are built in definition that can be used easily. However if you define some inside a specific project, it’s not really easy to add them. Of course it’s possible but not easy.

    We might consider allowing external object that implement the corresponding interface to be registered easily.

    That can also allow the ability to create raven plugins more easily.

    enhancement 
    opened by shulard 0
  • Allow to generate Request object based on documented examples

    Allow to generate Request object based on documented examples

    It’s possible to add examples inside the OpenAPI documentation. Since Raven is able to generate requests to be validated I think that it’ll be awesome to retrieve documented examples and build requests with the values…

    Today, raven isn’t able to parse the OpenAPI documentation by itself. It also doesn’t provide any interface to be implemented about the parsing logic. We might consider being compatible with the well known parsers ?

    enhancement help wanted 
    opened by shulard 0
Releases(v0.2.0)
  • v0.2.0(Oct 29, 2022)

    Thanks to @emyrtille, we have now a more valid dependencies constraint definition. Having strict constraints on a lib is not really helpful because it blocks installing the tool on a lot of different projects.

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Oct 6, 2022)

    This release introduces a new object in the CHStudio\Raven\Http\Factory namespace named: RequestUriParametersResolver.

    Its goal is to allow resolving URI parameters value using a ValueResolverInterface object. You can use Faker or your own logic to resolve your params ^^

    Check the updated README to know how to use it.

    Also the BodyResolverInterface was renamed ValueResolverInterface to be more convenient with the logic. It will be used on different kind of things, not just the Body.

    Source code(tar.gz)
    Source code(zip)
  • v0.0.0(Oct 4, 2022)

Owner
CH Studio
We imagine solutions for your business applications, specialized in PHP, we develop solid applications that respect the best industrialization processes.
CH Studio
Opens an interactive PHP console for running and testing PHP code.

wp-cli/shell-command Opens an interactive PHP console for running and testing PHP code. Quick links: Using | Installing | Contributing | Support Using

WP-CLI 20 Nov 4, 2022
Easily add logs anywhere in your Magento 2 code

Magento 2 Simple Log Easily add logs anywhere in the code (like Magento 1). Requirements Requires Magento 2 in any version. Installation Add the Log.p

Matthieu Vion 19 Dec 27, 2021
Generate API documentation for humans from your Laravel codebase.✍

Scribe v3 is out now! Scribe helps you generate API documentation for humans from your Laravel/Lumen/Dingo codebase. See a live example at demo.scribe

Knuckles 1k Jan 9, 2023
Easily create and work with code snippets from PHP

code-snippets Easily create and work with code snippets from source code files of any type in PHP. The original code this package is based on was borr

Permafrost Software 8 Sep 4, 2022
Documentation on clean coding and demonstration of studied clean coding principals with PHP.

practice-php-clean-code Documentation on clean coding and demonstration of studied clean coding principals with PHP. The document contained in this re

Ferdous Islam 1 Feb 21, 2022
Fly50W is a new language which helps you build simple apps using more than 500k lines of code easily.

Fly50W is a new language which helps you build simple apps using more than 500k lines of code easily. Installation

null 4 Jun 22, 2022
Easily run code asynchronously

Asynchronous and parallel PHP This library provides a small and easy wrapper around PHP's PCNTL extension. It allows running of different processes in

Spatie 2.3k Jan 7, 2023
Simple IT Documentation Solution for MSPs

SimpleMSPDoc RC 1.0 I wasn't happy with what other IT documention software had. I felt they over complicated things and required so much clicky clicky

null 4 Jun 5, 2022
Disclaimer: The documentation of this plugin is English at the moment, but I might go for Latin later down the line, just for the fun of it.

Quiritibus Plugin This repository is storing the custom plugin developed for the Quiritibus Latin Magazine website, currently being developed at: http

Alkor András 1 Jan 19, 2022
Preload your sweet sweet code to opcache with a composer command, making your code faster to run.

Composer Preload Preload your sweet sweet code to opcache with a composer command, making your code run faster. Composer Preload is a composer plugin

Ayesh Karunaratne 197 Dec 6, 2022
Simple HTTP smoke testing for your Symfony application

Shopsys HTTP Smoke Testing This package enables you to do simple HTTP smoke testing of your Symfony application. Basically, it generates a HTTP reques

Shopsys 65 Feb 3, 2022
The SensioLabs DeprecationDetector runs a static code analysis against your project's source code to find usages of deprecated methods, classes and interfaces

SensioLabs DeprecationDetector CAUTION: This package is abandoned and will no longer receive any updates. The SensioLabs DeprecationDetector runs a st

QOSSMIC GmbH 389 Nov 24, 2022
A Laravel test build by Incline Start-up Agency. Testing Git and framework functions.

Incognito-Confessions A laravel test build by Incline Start-up Agency. Testing Git and framework functions. Description A laravel starter for future t

null 6 Nov 9, 2022
PSpec is a testing framework for PHP, influenced by RSpec and jest. 🧪 This repo is a MIRROR of the GitLab source repository.

PSpec PSpec is a testing framework for PHP, influenced by RSpec and jest. This project is experimental and still needs a lot of work. Example // src/C

CodingPaws 0 Mar 31, 2022
Allows Admins to quickly login as any user in the system during development/testing

SilverStripe User Switcher The module adds a small form both in the frontend to quickly login as any user in the system. The intended use is in testin

LiveSource 15 Mar 1, 2021
Testing utilities for the psr/log package that backs the PSR-3 specification.

FIG - Log Test Testing utilities for the psr/log package that backs the PSR-3 specification. Psr\Log\Test\LoggerInterfaceTest provides a base test cla

PHP-FIG 3 Nov 19, 2022
💨 Smoke testing tool written in PHP

Cigar A smoke testing tool inspired by symm/vape Similar tools include: Blackfire Player Installation Install via composer: composer require brunty/ci

Matt Brunt 156 Oct 14, 2022
⚗️ Adds code analysis to Laravel improving developer productivity and code quality.

⚗️ About Larastan Larastan was created by Can Vural and Nuno Maduro, got artwork designed by @Caneco, is maintained by Can Vural, Nuno Maduro, and Vik

Nuno Maduro 4.4k Jan 4, 2023