komoitokomoito MemberComments: 9 Received thanks: 1 Member since: June 2019 edited September 2019

Hi guys!

I have question about unit tests. How to execute shopware tests in shopware "composer" generated project with my custom plugin tests using one autoload.php file.

I noticed when I created shopware project by composer that we don't have tests folder inside, it is in vendor folder in shopware -> shopware -> tests folder. I want to have those tests executed with my plugin example tests in the same execution "context". I managed to do some very interesting stuff like creating another bootstrap.php unit tests file for shopware tests, but i managed to execute them seperate. When I tried to execute them together i have problem with autoload.php and missing classes. How do you handle such a things in composer project ? 

Here is some folder structure i created for the tests:
image

The code :
Tests-> Bootstrap.php
 

<?php

ini_set('error_reporting', E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');

require __DIR__ . '/../app/autoload.php';


class SwagTestKernel extends AppKernel
{
    /**
     * Static method to start boot kernel without leaving local scope in test helper
     */
    public static function start()
    {
        $kernel = new self('testing', true);
        $kernel->boot();

        $container = $kernel->getContainer();
        $container->get('plugins')->Core()->ErrorHandler()->registerErrorHandler(E_ALL | E_STRICT);

        /** @var \Shopware\Models\Shop\Repository $repository */
        $repository = $container->get('models')->getRepository('Shopware\Models\Shop\Shop');

        $shop = $repository->getActiveDefault();
        $shop->registerResources();
        //Register for containers
        //self::registerResources();


        $_SERVER['HTTP_HOST'] = $shop->getHost();
    }

    private static function registerResources() {

        /*we can register some resources here for example

        Shopware()->Container()->set('swag_test_example.test_service', new \SwagTestExample\Service\TestExampleService(
            Shopware()->Container()->get('shopware_storefront.list_product_service'),
            Shopware()->Container()->get('shopware_storefront.context_service')
        ));

        */
    }

}


SwagTestKernel::start();

phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false" backupStaticAttributes="false" bootstrap="./Bootstrap.php">
    <testsuite name="SwagExampleTest Test Suite">
        <directory>./../custom/plugins/SwagTestExample/Tests</directory>
    </testsuite>
    <php>
        <env name="APP_ENV" value="test"/>
    </php>
    <filter>
        <whitelist processUncoveredFilesFromWhitelist="true">
            <exclude>
                <directory suffix=".php">./../custom/plugins/SwagTestExample/Tests</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

ShopwareDefaultTestsBootstrap.php  - becuase i use another autload.php i don't have acces to basic configuration from env file (all code is in vendor etc )  so i have to improvise some config reading code. All tests seems to work but those are executed seperately. 

<?php

require __DIR__ . '/./../vendor/shopware/shopware/autoload.php';


class TestKernel extends \Shopware\Kernel
{
    /**
     * Static method to start boot kernel without leaving local scope in test helper
     */
    public static function start()
    {
        $kernel = new self('testing', true);
        $kernel->boot();

        $container = $kernel->getContainer();
        $container->get('plugins')->Core()->ErrorHandler()->registerErrorHandler(E_ALL | E_STRICT);

        /** @var \Shopware\Models\Shop\Repository $repository */
        $repository = $container->get('models')->getRepository('Shopware\Models\Shop\Shop');

        $shop = $repository->getActiveDefault();
        $shop->registerResources();

        $_SERVER['HTTP_HOST'] = $shop->getHost();
    }

    protected function getConfigPath()
    {
        return __DIR__ . '/../vendor/shopware/shopware/tests/Functional/config.php';
    }

    protected function initializeConfig() {
        parent::initializeConfig();

        //Setup database connection configuration for phpunit tests.
        $this->config['db'] = [
            'username' => $this->getEnvFromFile('DB_USERNAME'),
            'password' => $this->getEnvFromFile('DB_PASSWORD'),
            'dbname' => $this->getEnvFromFile('DB_DATABASE'),
            'host' => $this->getEnvFromFile('DB_HOST'),
            'port' => $this->getEnvFromFile('DB_PORT'),
            'charset' => 'utf8mb4',
            'adapter' => 'pdo_mysql',
        ];
    }

    private function readEnvFile() {
        $fileContent = file_get_contents(__DIR__.'/../.env');
        return $fileContent;
    }

    private function getEnvFromFile($env) {
        $content = $this->readEnvFile();
        $lines = explode(PHP_EOL , $content);

        $linesCount = count($lines);

        for($i = 0 ; $i <$linesCount; $i++) {
            $line = $lines[$i];
            $containsEnv =  strpos($line,$env) !== false;
            if($containsEnv) {
                $envValue = $this->getEnvFromLine($line,$env);
                return $envValue;
            }
        }

        return '';
    }

    private function getEnvFromLine($line,$env) {
        $lines = explode('=',$line);
        $linesCount = count($lines);
        $isEnoughLines = $linesCount === 2;
        if($isEnoughLines) {
            return str_replace('"','',$lines[1]); //value
        } else {
            throw new Exception('The value for '.$env.' is not defined');
        }



    }

}

TestKernel::start();

And xml file for configuration shopware tests. shopware-phpunit.xml.dist

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

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.5/phpunit.xsd";
         bootstrap="./ShopwareDefaultTestsBootstrap.php"
         colors="true"
         backupGlobals="true"
         beStrictAboutOutputDuringTests="true"
         beStrictAboutResourceUsageDuringSmallTests="true"
         beStrictAboutTestsThatDoNotTestAnything="true"
         beStrictAboutTodoAnnotatedTests="true"
         verbose="true">

    <testsuites>
        <testsuite name="Shopware_AllTests">
            <directory>./../vendor/shopware/shopware/tests/Unit</directory>
            <directory>./../vendor/shopware/shopware/tests/Functional</directory>
        </testsuite>
    </testsuites>
    <php>
        <env name="DATABASE_URL" value="app_mysql"/>
    </php>
    <groups>
        <exclude>
            <group>disable</group>
        </exclude>
    </groups>

    <filter>
        <whitelist>
            <directory suffix=".php">./../vendor/shopware/shopware/engine/Shopware/</directory>
            <exclude>
                <directory>./../vendor/shopware/shopware/engine/Shopware/Plugins/Community</directory>
                <directory>./../vendor/shopware/shopware/engine/Shopware/Components/Xml</directory>
            </exclude>
        </whitelist>
    </filter>
</phpunit>

It would be nice to have those tests in one configuration file and with one context of testing. I think i am missing something important in my code could you guys please give me a hint or just write what I am doing wrong. Thanks a lot for any input from you! :) 

Answers

  • komoitokomoito MemberComments: 9 Received thanks: 1 edited September 2019 Member since: June 2019

    Hi guys I managed to run my tests with Shopware Tests. How to do it ? 

    First I was wondering why shopware classses are not included in my autoload. I dig deeper and went to composer.json. 

    Aand I just used psr-4 in autload section, to generete my autoload files, by composer dump-autload command

    autoload": {
            "classmap": [
                "app/Application.php",
                "app/AppKernel.php",
                "app/ShopwareVersion.php"
            ],
            "psr-4": {
                "Shopware\\Tests\\": "vendor/shopware/shopware/tests"
            }
        },

    So now i can just include my shopware tests to test my code and functionalities and execute them together. Here is example of phpunit.xml

     

    <?xml version="1.0" encoding="UTF-8"?>
    <phpunit backupGlobals="truw" backupStaticAttributes="false" bootstrap="./Bootstrap.php">
        <testsuites>
            <testsuite name="SwagExampleTest Test Suite">
                <directory>./../custom/plugins/SwagTestExample/Tests</directory>
            </testsuite>
          <testsuite name="Shopware_AllTests">
                <directory>./../vendor/shopware/shopware/tests/Unit</directory>
                <directory>./../vendor/shopware/shopware/tests/Functional</directory>
            </testsuite>
        </testsuites>
        <php>
            <env name="APP_ENV" value="test"/>
        </php>
    </phpunit>

     

    Thanked by 1tim_binder
Sign In or Register to comment.