Search code examples
symfonyphpunitbundle

Testing Reusable Symfony Bundles with PHPUnit Bridge


I recently ran across PHPUnit Bridge, and have been using it in any of my standalone Symfony apps. However, I noticed some deprecation notices coming through for a reusable bundle dependency that we maintain.

To diagnose, I opened up the reusable bundle project and installed symfony/phpunit-bridge, but after running phpunit noticed that there were no deprecation notices, etc, being output for the project.

So how do you utilize the symfony/phpunit-bridge package with reusable bundles?


Solution

  • I noticed some deprecation notices coming through for a reusable bundle dependency that we maintain.

    To diagnose, I opened up the reusable bundle project and installed symfony/phpunit-bridge, but after running phpunit noticed that there were no deprecation notices, etc, being output for the project.

    The fact that the same code does not always trigger the same warnings may indicate that the tests are different.

    If this comes from PHP code, you can see tested and untested code by using PHP_CodeCoverage. When you use PHPUnit, you can add an option in order to generate a code coverage report, e.g. phpunit … --coverage-html cov/ will generate an HTML report in the cov/ directory. By comparing the outputs, you can see if tests launched from Symfony call the same code that the tests launched from the Bundle.

    If the tests are different, you can set up a Symfony environment for your bundle:

    Create a TestKernel

    <?php
    // Tests/Controller/App/AppKernel.php
    
    use Symfony\Component\HttpKernel\Kernel;
    use Symfony\Component\Config\Loader\LoaderInterface;
    
    class AppKernel extends Kernel
    {
        public function registerBundles()
        {
            $bundles = array(
                // Dependencies
                new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
                [...]
                // My Bundle to test
                new Beberlei\WorkflowBundle\BeberleiWorkflowBundle(),
            );
    
            return $bundles;
        }
    
        public function registerContainerConfiguration(LoaderInterface $loader)
        {
            // We don't need that Environment stuff, just one config
            $loader->load(__DIR__.'/config.yml');
        }
    }
    

    Creating the config.yml

    # Tests/Controller/App/config.yml
    framework:
        secret:          secret
        charset:         UTF-8
        test: ~
        router:          { resource: "%kernel.root_dir%/routing.yml" }
        form:            true
        csrf_protection: true
        validation:      { enable_annotations: true }
        templating:      { engines: ['twig'] }
        session:
            auto_start:     false
            storage_id: session.storage.filesystem
    
    monolog:
        handlers:
            main:
                type:         fingers_crossed
                action_level: error
                handler:      nested
            nested:
                type:  stream
                path:  %kernel.logs_dir%/%kernel.environment%.log
                level: debug
    

    Creating the routing.yml

    # Tests/Controller/App/routing.yml
    BeberleiWorkflowBundle:
        resource: "@BeberleiWorkflowBundle/Controller/"
        type:     annotation
        prefix:   /
    

    Modifying the phpunit.xml.dist

    <!-- phpunit.xml.dist -->
    <phpunit bootstrap="Tests/bootstrap.php">
        <php>
            <server name="KERNEL_DIR" value="Tests/Controller/App" />
        </php>
    </phpunit>
    

    Then, you can add "symfony/symfony": "~2.3" in the required packages in composer.json and install the packages. Future tests will boot this AppKernel and perform tests in a complete Symfony environment.