Skip to content

Innmind/black-box-symfony

Repository files navigation

black-box-symfony

Build Status Type Coverage

This package is an extension of innmind/black-box to help test Symfony applications.

Installation

composer require innmind/black-box-symfony

Usage

use Innmind\BlackBox\{
    Runner\Assert,
    Symfony\Application,
};

return static function() {
    yield test(
        'Login',
        function(Assert $assert) {
            $app = Application::new($assert); // This assumes the kernel class is 'App\Kernel'
            $response = $app
                ->json()
                ->post('/login', [
                    'username' => 'john',
                    'password' => 'doe',
                ]);
            $response
                ->statusCode()
                ->is(200);

            $content = $response->body()->json();
            $assert
                ->array($content)
                ->hasKey('token');
            $token = $content['token'];

            $app
                ->get('/me')
                ->statusCode()
                ->is(200);
        },
    );
};

Model Based Testing

By representing the application as a standalone object we can consider it as a system to test and so test it via properties.

use Innmind\BlackBox\{
    Set,
    Property,
    Runner\Assert,
    Symfony\Application,
};

/**
 * @implements Property<Application>
 */
final class Login implements Property
{
    public static function any(): Set
    {
        return Set\Elements::of(new self);
    }

    public function applicableTo(object $app): bool
    {
        return true;
    }

    public function ensureHeldBy(Assert $assert, object $app): object
    {
        response = $app
            ->json()
            ->post('/login', [
                'username' => 'john',
                'password' => 'doe',
            ]);
        $response
            ->statusCode()
            ->is(200);

        $content = $response->body()->json();
        $assert
            ->array($content)
            ->hasKey('token');
        $token = $content['token'];

        $app
            ->get('/me')
            ->statusCode()
            ->is(200);

        return $app;
    }
}

And you would run it via:

use Innmind\BlackBox\{
    Set,
    Properties,
    Runner\Assert,
    Symfony\Application,
};

return static function() {
    yield proof(
        'Login',
        given(Login::any()),
        function(Assert $assert, Login $login) {
            $app = Application::new($assert);

            $login->ensureHeldBy($assert, $app);
        },
    );
    // and you can even test a sequence of properties to simulate a user actions
    yield proof(
        'No user interaction should crash the app',
        given(Set\Properties::any(
            Login::any(),
            AnotherProperty::any(),
            // etc...
        )),
        function(Assert $assert, Properties $properties) {
            $app = Application::new($assert);

            $properties->ensureHeldBy($assert, $app);
        },
    );
}

PHPUnit emulation

BlackBox is able to run PHPUnit tests and this extension allows to run functional tests. For this to work you only need to prefix the Symfony\Bundle\FrameworkBundle\Test\WebTestCase by Innmind\BlackBox\.

And the file to run BlackBox would look like:

<?php
declare(strict_types = 1);

require 'vendor/autoload.php';

use Innmind\BlackBox\Application;
use Innmind\BlackBox\PHPUnit\Load;
use Symfony\Component\Dotenv\Dotenv;

(new Dotenv())->bootEnv('.env', 'test');

Application::new($argv)
    ->disableMemoryLimit()
    ->scenariiPerProof(1)
    ->tryToProve(Load::directory('tests/'))
    ->exit();

Warning: custom assertions provided by Symfony are not supported.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages