Hack, plug, play – and test

Unit Tests mit Shopware
Kommentare

Aufbauend auf dem Shopware-Plug-in aus dem ersten Teil der Serie werden wir diesmal folgende Dinge bearbeiten: das Einrichten einer geeigneten Testumgebung für Unit Tests, die Ausführung der vorhandenen Tests und die Entwicklung eines eigenen Unit Tests für das SloganOfTheDay-Plug-in.

Im Artikel „Plug-ins mit Shopware“ haben Oliver Denter und Stephan Pohl ein Plug-in entwickelt, welches das Shoplogo durch einen zufälligen Slogan ersetzt, der vorher konfiguriert werden konnte. Darauf aufbauend wollen wir nun einen Unit Test erstellen. Wer das Plug-in benötigt, kann es unter GitHub herunterladen. Wir werden unseren Test auf die vorhandenen Tests, die Shopware auf GitHub veröffentlicht hat, aufbauen. In Zukunft soll es ein eigenes Unit-Test-Framework speziell für die Plug-in-Entwicklung geben.

Testumgebung

Als Testumgebung benötigen wir einen Webserver, der die Shopware-Voraussetzungen erfüllt. Zusätzlich wird das PEAR-Modul PHPUnit mit der Erweiterung DBUnit benötigt. Wer schon eine funktionierende Testumgebung inklusive einer lauffähigen Installation des Shopware-Masterbranches von GitHub hat, kann diesen Abschnitt getrost überspringen.

Als Grundlage für unser Testsystem verwenden wir eine minimale Installation von Debian. Alle weiteren benötigten Module und Einstellung sind hier detailliert beschrieben. Zusätzlich zu den Shopware-Voraussetzungen benötigen wir PHP-Pear und PHPUnit mit der Erweiterung DBUnit auf unserem Testsystem, zu installieren wie folgt:

pear config-set auto_discover 1
pear install pear.phpunit.de/PHPUnit
pear install phpunit/DbUnit

Nachdem wir nun alle Bedingungen erfüllt haben, können wir uns an die Installation des aktuellen Masterbranches von Shopware machen. Dazu klonen wir den aktuellen Masterbranch per git clone (https://github.com/ShopwareAG/shopware-4.git). Anschließend setzen wir die benötigten Verzeichnisrechte wie folgt:

chmod 755 config.php
chmod 755 -R cache
chmod 755 -R files
chmod 755 -R media
chmod 755 -R engine/Library/Mpdf/tmp
chmod 755 -R engine/Library/Mpdf/ttfontdata
chmod 755 -R engine/Shopware/Plugins/Community

Je nach Serverkonfiguration kann es sein, dass die Rechte 755 nicht ausreichen und der Server die vollen Rechte 777 benötigt. Mithilfe von ANT (ggfs. muss ANT noch installiert werden) und einer von Shopware bereitgestellten Konfigurationsdatei können wir mit folgendem Aufruf unsere Datenbankverbindung einrichten und die notwendigen Datenbanktabellen importieren:

cd build/
ant -Ddb.user=#user# -Ddb.password=#password# -Ddb.name=#Shopware# build-database build-config

Abschließend holen wir uns noch die aktuellen Demodaten, dazu gehen wir ins Root-Verzeichnis unserer Shopware-Installation und führen folgende Befehle aus:

wget -O demo.zip files.shopware.de/download.php?package=demo
    unzip demo.zip

Wenn nun alles richtig installiert und konfiguriert wurde, können wir in das Verzeichnis /TESTS/SHOPWARE/ gehen und mit einem simplen Aufruf von phpunit alle vorhandenen Tests durchführen. Die Ausgabe sollte dann ungefähr so aussehen wie in Abbildung 1.

Abb. 1: Ergebnis der Ausführung der vorhandenen Tests

Abb. 1: Ergebnis der Ausführung der vorhandenen Tests

Erstellung eines eigenen Unit Tests

In dem Verzeichnis /TESTS/SHOPWARE/TESTS/ befinden sich alle momentan vorhandenen Unit Tests von Shopware. Hier gibt es mehrere Verzeichnisse, die Tests für Components, Controllers, Modules und Plug-ins.

Unseren Unit Tests erstellen wir auf Grundlage des Google-Plug-in-Tests. Wir erstellen in dem Verzeichnis /TESTS/SHOPWARE/TESTS/PLUGINS/FRONTEND/ eine neue Datei mit dem Namen SloganOfTheDayTest.php und dem Grundgerüst aus Listing 1.

class Shopware_Tests_Plugins_Frontend_SloganOfTheDayTest extends Enlight_Components_Test_Plugin_TestCase
{
  protected $plugin;
  public function setUp()
  {
    parent::setUp();
    $this->plugin = Shopware()->Plugins()->Frontend()->SloganOfTheDay();
  }
  public function Plugin()
  {
    return $this->plugin;
  }
  public function testPostDispatch()
  {
  }
}

Mit der Hilfsfunktion Plugin() können wir im späteren Test mit $this->Plugin() anstatt Shopware()->Plugins()->Frontend()->SloganOfTheDay() auf unser Plug-in und dessen Funktionen zugreifen. Nun fügen wir zu unserer testPostDispatch()-Funktion Folgendes hinzu, alle weiteren Quellcodeschnipsel werden danach eingefügt:

$request = $this->Request()
->setModuleName('frontend')
->setDispatched(TRUE);

Dadurch haben wir nun das benötigte Request Object für ein Plug-in aus dem Frontend-Bereich erstellt. Anschließend füttern wir unser Plug-in noch mit Einstellungen, mit denen wir es prüfen möchten. Wir erstellen ein Array mit verschiedenen Slogans. Dieses Array wird später zur Überprüfung der getRandomSlogan()-Funktion benötigt:

$slogans = array(
  'mmmmh... shopware',
  'shopware ist mein Lebenselixier',
  'shopware weiss, was Frauen wünschen',
  'shopware flirtet gern'
); 

Nun füllen wir die Plug-in-Konfiguration. Mit dem Parameter setAllowModifications() können wir noch nachträglich die Konfiguration des Plug-ins beeinflussen. Wie vom Plug-in gefordert, verbinden wir die einzelnen Array-Elemente von $slogans mit einem Semikolon zu einem String:

$this->Plugin()->Config()
->setAllowModifications()
->set('slogans', implode(';', $slogans));

Anschließend erstellen wir ein neues Enlight_View_Default-Objekt und laden das Standardtemplate frontend/index/index.tpl:

$view = new Enlight_View_Default(
  Shopware()->Template()
);
$view->loadTemplate('frontend/index/index.tpl');

Danach erstellen wir ein neues Mock-Objekt von der Enlight_Controller_Action-Klasse:

$action = $this->getMock(
  'Enlight_Controller_Action',
  NULL, // array('detailAction')
  array($request, $this->Response())
);

Nun übergeben wir unserem Mock-Objekt die aktuelle View-Instanz:

$action->setView($view);
$eventArgs = $this->createEventArgs()->setSubject($action);

Hier führen wir die Funktion onPostDispatchIndex aus dem Plug-in aus und fangen eventuelle Exceptions ab:

$e = NULL;
try {
  $this->Plugin()->onPostDispatchIndex($eventArgs);
} catch (Exception $e) {
}

Nun überprüfen wir mit Zuhilfenahme der PHPUnit-Methode assertNull(), ob wir eine Exception in der Ausführung haben:

$this->assertNull($e);

Hier wird getestet, ob in der View auch wirklich ein Slogan enthalten ist, den wir vorher über das $slogan-Array definiert haben:

$this->assertContains($view->slogan, $slogans);

Zu guter Letzt wird geschaut, ob das Template in der View geladen worden ist:

$this->assertContains(
  'frontend/plugins/slogan_of_the_day/index.tpl',
  $view->Template()->getTemplateResource()
)

Fazit

Auch wenn die Lernkurve zum Schreiben von Unit Tests für Shopware-Plug-ins am Anfang ziemlich steil ist, hilft es einem ungemein, in die vorhandenen Tests von Shopware zu schauen. Auf dieser Grundlage ist es bedeutend einfacher, seine eigenen Tests zu schreiben. Interessant wird es, wenn Shopware das eigene Unit-Test-Framework speziell für Plug-ins veröffentlicht: Damit sinkt die Lernkurve zum Erstellen von Unit Tests bestimmt deutlich und das Erstellen der Tests wird auch für Shopware-Einsteiger ein Kinderspiel.

Aufmacherbild: Abstract style illustration depicting printed circuit board components. von Shutterstock / Urheberrecht: Sam72

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -