Подтвердить что ты не робот

Функциональные тесты внутри автономного пакета Symfony2

Мне нужно сделать некоторые функциональные тесты непосредственно в отдельном комплекте. Я не хочу тестировать контроллер, просто взаимодействие между реальными службами.

Я хотел бы знать, есть ли стандартный/лучший способ сделать это. Я сделал это одним способом, но хотел бы знать, есть ли лучший.

4b9b3361

Ответ 1

Вот мое собственное решение (я суммирую весь процесс тестирования в автономном комплекте):

1. Во-первых, у хорошего пакета есть свой composer.json, чтобы определить его зависимости:

{
    "name": "my/own-bundle",
    "type": "symfony-bundle",
    "description": "Symfony2 bundle that provides ...",
    "keywords": ["my","own"],
    "license": "MIT",
    "authors": [
        {
            "name": "John Doe",
            "email": "[email protected]"
        }
    ],
    "require": {
        "php": ">=5.3.2",
        "symfony/framework-bundle": ">=2.3"
    },
    "require-dev": {
        "phpunit/phpunit": "3.7.*"
    },
    "autoload": {
        "psr-0": { "My\\OwnBundle": "" }
    },
    "target-dir": "My/OwnBundle",
    "minimum-stability": "dev"
}

Обратите внимание на использование зависимости от symfony/framework-bundle, которое необходимо для наших тестов сервисов. Вы, конечно, можете снизить зависимости при определении ваших собственных реальных зависимостей от ядра symfony.

В этом файле я могу обработать команду (сделать это), чтобы создать каталог поставщика моего пакета:

$ composer update

2. Затем я установил свой конфигурационный файл phpunit:

<!-- phpunit.xml.dist -->

<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false"
         bootstrap="Tests/bootstrap.php"
>
    <testsuites>
        <testsuite name="MyOwnBundle Test Suite">
            <directory>./Tests/</directory>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist>
            <directory>./</directory>
            <exclude>
                <directory>./Resources</directory>
                <directory>./Tests</directory>
                <directory>./vendor</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

3. Затем я установил загрузку php для автозагрузки класса в моем тестовом каталоге:

// Tests/bootstrap.php

$file = __DIR__.'/../vendor/autoload.php';
if (!file_exists($file))
{
    $file = __DIR__.'/../../../../../../vendor/autoload.php';
    if (!file_exists($file))
        throw new RuntimeException('Install dependencies to run test suite.');
}

$autoload = require_once $file;

Эти шаги являются стандартными для любого теста в отдельном комплекте.

4. Теперь я хочу имитировать приложение, чтобы сделать некоторые функциональные тесты для моих сервисов:

Мне нужен класс ядра:

// Tests/AppKernel.php (you can define it in a subdirectory /Fixtures if you prefer)

use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array();

        if (in_array($this->getEnvironment(), array('test'))) {
            $bundles[] = new Symfony\Bundle\FrameworkBundle\FrameworkBundle();
            $bundles[] = new My\OwnBundle\MyOwnBundle();
        }

        return $bundles;
    }

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config.yml');
    }
}

И соответствующий config.yml:

# Tests/config.yml

framework:
    secret: test
    session:
        storage_id: session.storage.mock_file

my_own:
    test: 2

Вот пример с макетом для сеанса. Не забудьте указать правильные узлы конфигурации инфраструктуры, если вы хотите иметь доступ к некоторым службам (если вы не укажете node session, у вас нет службы session).

5. Наконец, в моих тестовых классах я могу получить следующие службы:

// Tests/Functional/Handling/Handler.php

namespace My\OwnBundle\Tests\Functional\Handling;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class HandlerTest extends WebTestCase
{
    private $handler;

    protected function setUp()
    {
        require_once __DIR__.'/../../AppKernel.php';

        $kernel = new \AppKernel('test', true);
        $kernel->boot();
        $container = $kernel->getContainer();
        $this->handler = $container->get('my_own.handling.handler');
    }

    public function testHandle()
    {
        $this->assert($this->handler->handle());
    }
}