Environment (Production, Testing) in Functional-Tests

Hallo Shopware-Forum,

vorab, es wird ein bisschen länger :slight_smile:

In einem Plugin habe ich eigene API Controller, welche die Standard Shopware REST-API um eigene Endpunkte erweitern. Soweit, so gut. Ich habe jetzt Functional-Tests geschrieben, die wie folgt aufgebaut sind:

  1. Testdaten (wie z.B Kunden oder Artikel) in der DB anlegen, die für den Test notwendig sind
  2. Über einen HttpClient (Zend_Http_Client) einen entsprechenden Request (GET, POST usw) an die zu testende Route senden
  3. Response des Http Clients auswerten und notwendige Assertions ausführen

Alles kein Hexenwerk, und so sind sogar die Tests von Shopware selbst umegsetzt (siehe im Verzeichnis tests/Api) und an sich funktioniert auch alles wunderbar. Aber:

Ich würde gerne alle Functional-Tests gerne in einer getrennten Datenbank ausführen, so dass Testdaten in einer von meiner Development-DB getrennt auflaufen. Diese DB ist auch komplett leer, und wird erst zur Testausführung mit Testedaten bestückt.

Dazu habe ich zunächst im Shopware Root verzeichnis eine config_testing.php angelegt, in der die entsprechende Konfiguration zur Test-DB konfiguriert ist.

Wenn ich jetzt allerdings die API Endpunkte testen will, mache ich ja einen tatsächlichen Request auf die REST-Route. Im Endeffekt also vergleichbar, wenn ich mit Postman oder ähnluchen REST-Client Tools einen Request an einen Endpunkte sende. Und somit ist das Environment (also die Umgebung, in welcher der HttpKernel und Shopware läuft) wieder auf production, was in der shopware.php im Root Verzeichnis gesetzt wird, wenn der HttpKernel gestartet wird.

Das ist in sofern ungünstig, da dadurch zwei getrennte Datenbanken verwendet werden:

Die Testdaten werden wie erwaretet in der Datenbank gespeichert, die in der config_testing.php definiert wurde, da die Tests mit dem TestKernel (siehe tests/Functional/bootstrap.php) ausgeführt werden.

Der HTTP Request auf die REST-Endpunkte nutzen meine Development-Datenbank, da hier die config.php verwendet wird.

Dadurch schlagen die Tests natürlich fehl, weil die Daten nicht (oder anders) vorhanden sind, als erwaretet.

Als unschönen kleinen Workaround, der für mich nur lokal funktioniert habe ich die shopware.php im Root wie folgt angepasst:

use Shopware\Kernel;
use Shopware\Components\HttpCache\AppCache;
use Symfony\Component\HttpFoundation\Request;

$environment = getenv('SHOPWARE_ENV') ?: getenv('REDIRECT_SHOPWARE_ENV') ?: 'production';

if ($_SERVER['HTTP_USER_AGENT'] === 'testing') {
    $environment = 'testing';
}

$debug = ! in_array($environment, ['production', 'testing']);

$kernel = new Kernel($environment, $debug);

Es wird also der User Agent vom Request ausgewertet, den ich wiederum in meinen Tests entsprechend im HTTP Client definiert habe:

// ...

$adapter = new Zend_Http_Client_Adapter_Curl();
$adapter->setConfig($adapterConfig);
$client = new Zend_Http_Client();
$client->setAdapter($adapter);
$client->setConfig(['useragent' => 'testing']);

// ...

Das ist natürlich unschön und funktioniert nur bei mir lokal. 

Nach so viel Text jetzt meine Frage:

  • Was gibt es hier für Alternativen, die besser sind, als die Anpassung der shopware.php Datei?
  • Kann ich zur Laufzeit das Environment im Kernel/Shopware ändern?

Vielen Dank wer bis hier zum Ende gelesen hat :wink: Und natürlich für hilfreiche Anregungen und Antworten!

Hi,

statt die shopware.php amzupassen, kannst du es auch mit der .htaccess bzw. mit der ServerConfig machen.
Es wird ja eine Environment-Variable in der shopware.php abgefragt.

Gruß Heiner