Automated tests in plugins

Version

6.0.0 or newer

Table of contents

Overview

To ensure your plugin's functionality, it's highly recommended to automatically test your source code. For this purpose, you can easily setup a PHPUnit testing environment for plugins.

This quick HowTo requires you to have a proper working plugin first.

Setup

Basically, the following is just a suggestion on how to setup PHPUnit with your plugin. This is by no means a hard requirement, feel free to create your own testing suite.

PHPUnit config file

PHPUnit is configured using a phpunit.xml.dist file. Read more about the possible configurations of the phpunit.xml.dist file here.

Here's what your plugin's phpunit.xml.dist file could look like:

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

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/7.1/phpunit.xsd"
         bootstrap="../../../vendor/shopware/platform/src/Core/TestBootstrap.php"
         cacheResult="false">

    <php>
        <ini name="error_reporting" value="-1"/>
        <server name="KERNEL_CLASS" value="Shopware\Development\Kernel"/>
        <env name="APP_ENV" value="test"/>
        <env name="APP_DEBUG" value="1"/>
        <env name="APP_SECRET" value="s$cretf0rt3st"/>
        <env name="SHELL_VERBOSITY" value="-1"/>
    </php>

    <testsuites>
        <testsuite name="Example Testsuite">
            <directory>tests/</directory>
        </testsuite>
    </testsuites>

    <filter>
        <whitelist>
            <directory suffix=".php">./</directory>
        </whitelist>
    </filter>
</phpunit>

You're also free to add and remove configurations, so the testsuite perfectly fits your needs. Important to note is the bootstrap configuration in the phpunit element. In this example, you're required to put your tests into the tests directory.

Here's an example test, which simply tries to instantiate every .php class, to see if any used core classes went missing:

<?php declare(strict_types=1);

namespace Swag\PluginTestingTests;

use Shopware\Core\Framework\Test\TestCaseBase\IntegrationTestBehaviour;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Finder\Finder;

class UsedClassesAvailableTest extends TestCase
{
    use IntegrationTestBehaviour;

    public function testClassesAreInstantiable(): void
    {
        $namespace = str_replace('\Test', '', __NAMESPACE__);

        foreach ($this->getPluginClasses() as $class) {
            $classRelativePath = str_replace(['.php', '/'], ['', '\\'], $class->getRelativePathname());

            $this->getMockBuilder($namespace . '\\' . $classRelativePath)
                ->disableOriginalConstructor()
                ->getMock();
        }

        // Nothing broke so far, classes seem to be instantiable
        $this->assertTrue(true);
    }

    private function getPluginClasses(): Finder
    {
        $finder = new Finder();
        $finder->in(realpath(__DIR__ . '/../'));
        $finder->exclude('Test');
        return $finder->files()->name('*.php');
    }
}

Make sure to have a look at the IntegrationTestBehaviour trait, which comes in with some handy features, such as automatically setting up a database transaction or clearing the cache before starting your tests.

Executing the tests

For easier usage, you could create a batch file called phpunit.sh into a bin directory of your plugin. Its only purpose then would be executing the PHPUnit testsuite. Make sure the path in the following file actually fits.

#!/usr/bin/env bash
./../../../vendor/bin/phpunit

Now you can simply run bin/phpunit.sh inside your plugin root directory to execute your plugin's tests. Also make sure to have a look at the Symfony PHPUnit documentation.

Source

There's a GitHub repository available, containing this example source. Check it out here.

Was this article helpful?