PHP Unit Tests mit Magento

11
PHPUnit Tests mit Magento Ist der Einsatz der Magento 2 Testsuite in Magento möglich? Und wie läuft die Portierung? Index: Mögliche Testverfahren Portierung der Testsuite Anlegen von Testdaten Probleme beim Einsatz der Testsuite Fazit www.techdivision.com 1 TechDivision GmbH PHPUnit Tests mit Magento

description

Eine der größten Schwächen von Magento, wenn man im Vergleich zu anderen Shopsystemen überhaupt von Schwächen sprechen kann, besteht sicherlich im Fehlen einer PHPUnit-Testsuite analog der, die mit Magento 2 eingeführt wird. Da seitens Magento momentan kein finaler Fertigstellungstermin für Magento 2 genannt wurde, wird Magento sicherlich noch länger als ursprünglich erwartet für Projekte zum Einsatz kommen. Anscheinend wird dem auch seitens Magento Rechnung getragen, da sich seit Version CE 1.7.x sowie EE 1.12.x auch hinsichtlich der Testbarkeit mit PHPUnit einiges getan hat. Jeder Entwickler, der mit Magento arbeitet, vermisst sicherlich schmerzlich eine Testsuite, die die Basisfunktionalität von Magento mit Unit- und Integrationsstest automatisiert testbar macht. Zusätzlich sollen natürlich auch die eigenen Entwicklungen für sich sowie in Abhängigkeit der Basisfunktionalität testbar sein. Sieht man sich die Testsuite von Magento 2 etwas detaillierter an, ist gut erkennbar, in welche Richtung Magento hier künftig gehen wird. Nachdem die Qualität für die Solution Partner als eines der zentralen Kriterien in die Bewertung des Partners mit einfließt, stellt Magento seinen Entwicklungspartnern künftig mit der Testsuite und dem Magento Automated Testing Guide [1] die Tools für die notwendige Verbesserung der Qualität, und somit auch der Partnerbewertung durch Magento, zur Verfügung. Dieser Artikel beschreibt die notwendigen Schritte zur Migration der Testsuite von Magento 2 auf Magento und zeigt anhand von Beispielen diverse Einsatzmöglichkeiten sowie die mögliche Integration in einen Build- und Deploymentprozess.

Transcript of PHP Unit Tests mit Magento

PHPUnit Tests mit MagentoIst der Einsatz der Magento 2 Testsuite in Magento möglich? Und wie läuft die Portierung?

Index:

Mögliche Testverfahren

Portierung der Testsuite

Anlegen von Testdaten

Probleme beim Einsatz der Testsuite

Fazit

www.techdivision.com

1TechDivision GmbH PHPUnit Tests mit Magento

Magento stellt seinen Entwicklungspartnern künftig die Testsuite und den Magento Automated Testing Guide [1] zur Verfügung.

Eine der größten Schwächen von Magento, wenn man im

Vergleich zu anderen Shopsystemen überhaupt von

Schwächen sprechen kann, besteht sicherlich im Fehlen

einer PHPUnit-Testsuite analog der, die mit Magento 2

eingeführt wird. Da seitens Magento momentan kein finaler

Fertigstellungstermin für Magento 2 genannt wurde, wird

Magento sicherlich noch länger als ursprünglich erwartet für

Projekte zum Einsatz kommen. Anscheinend wird dem auch

seitens Magento Rechnung getragen, da sich seit Version

CE 1.7.x sowie EE 1.12.x auch hinsichtlich der Testbarkeit

mit PHPUnit einiges getan hat.

Jeder Entwickler, der mit Magento arbeitet, vermisst

sicherlich schmerzlich eine Testsuite, die die

Basisfunktionalität von Magento mit Unit- und

Integrationsstest automatisiert testbar macht. Zusätzlich

sollen natürlich auch die eigenen Entwicklungen für sich

sowie in Abhängigkeit der Basisfunktionalität testbar sein.

Sieht man sich die Testsuite von Magento 2 etwas

detaillierter an, ist gut erkennbar, in welche Richtung

Magento hier künftig gehen wird. Nachdem die Qualität für

die Solution Partner als eines der zentralen Kriterien in die

Bewertung des Partners mit einfließt, stellt Magento seinen

Entwicklungspartnern künftig mit der Testsuite und dem

Magento Automated Testing Guide [1] die Tools für die

notwendige Verbesserung der Qualität, und somit auch der

Partnerbewertung durch Magento, zur Verfügung.

Dieser Artikel beschreibt die notwendigen Schritte zur

Migration der Testsuite von Magento 2 auf Magento und

zeigt anhand von Beispielen diverse Einsatzmöglichkeiten

sowie die mögliche Integration in einen Build- und

Deploymentprozess.von Tim Wagner

Die Testsuite bringt Tests für die gängigsten vier

Testverfahren mit. So werden Unit-, Integrations- und

Performancetests ausgeliefert. Zusätzlich enthält die Suite

Tests für die statische Code-Analyse. Bis auf die

Performance Tests bauen alle Tests auf PHPUnit [2] von

Sebastian Bergmann auf. Dieser Artikel beschäftigt sich

hauptsächlich mit den Unit- und den Integrationstests, da

diese für die meisten Entwickler die größte Bedeutung

haben. Durch die Integration dieser beiden Testverfahren

wird die Qualität und somit die auch Wartbarkeit von

Magento-Projekten mittel- und langfristig erheblich steigen.

Auf die statische Code-Analyse möchte ich in diesem Artikel

nicht näher eingehen, da diese im Rahmen des Build- und

Deploymentprozesses separat abgehandelt werden kann,

und sie zum anderen zum Migrationszeitpunkt nur sehr

rudimentär seitens Magento implementiert war. Auch auf

die Performancetests wird nicht näher eingegangen, da

diese über JMeter umgesetzt und ebenfalls separat

aufgerufen werden müssen.

Mögliche Testverfahren

2TechDivision GmbH PHPUnit Tests mit Magento

Portierung der TestsuiteAufbauend auf unserem Build- und Deploymentprozess, bei

dem der Entwickler die Möglichkeit hat, über das

eingesetzte Buildtool, in unserem Fall ANT [3], jederzeit

automatisiert eine neue Magento-Instanz zu erstellen, war,

neben einer spürbaren Steigerung der Qualität, eines der

Primärziele der Portierung, dass beim Erstellen einer neuen

Entwicklungsinstanz dem Entwickler die Tests umgehend

zur Verfügung stehen und diese somit nahtlos in alle

Entwicklungsprozesse integriert sind. Die Portierung erfolgte

in drei Schritten und begann im April 2012.

Schritt 1: Testsuite als Extension bereitstellen

Im ersten Schritt wurden die zum Portierungszeitpunkt

aktuellen Sourcen von Magento 2 aus dem GIT Repository

geclont. Anschließend wurde die Testsuite im Rahmen einer

eigenen Extension so aufgesetzt, dass sie zum einen in

jedem Magento-Shop ab Version CE 1.7.x/EE 1.12.x

installiert, und zum anderen über einen automatisierten

Prozess für jede zukünftige Magento-Version ein um die

Testsuite erweitertes Installationspaket erstellt und auf

einem Buildserver bereitgestellt werden kann.

Die Extension enthält somit, wie in Illustration 1 dargestellt,

neben der notwendigen Konfiguration und den Helper-

Klassen im app-Verzeichnis den Bootstrapper (1), die

Verzeichnisse dev (2), das aus den Magento-2-Sourcen

übernommen wurde, sowie die Verzeichnisse lib +

downloader (5 + 3).

Das lib-Verzeichnis enthält einige für Magento 2 spezifische

Klassen, die die Testsuite jedoch für die Initialisierung

benötigt. Im downloader-Verzeichnis befinden sich die von

früheren Magento-1-Versionen benötigten Dateien für den

Downloader. Dieser wird zwar mit aktuellen Magento-

Versionen nicht mehr ausgeliefert, jedoch für das

erfolgreiche Erstellen des Code-Coverage-Reports benötigt.

Magento referenziert hier in einigen Dateien immer noch

fälschlicherweise PEAR-Klassen (4), die für den Betrieb

eigentlich nicht mehr benötigt werden. Bei der statischen

Code-Analyse mit PHPUnit tritt jedoch ein Fatal Error auf,

falls diese Klassen nicht im downloader-Verzeichnis

gefunden werden können. Optional könnte auch über die

Whitelist in der phpunit.xml.dist auf die Prüfung der

entsprechenden Sourcen durch PHPUnit beim Erstellen des

CodeCoverage Reports verzichtet werden.

Schritt 2: Anpassen der Testsuite an Magento

Im zweiten Schritt musste die mit Magento 2 ausgelieferte

Testsuite an Magento angepasst werden. Zu Beginn der

Migration hatten wir Magento CE 1.6.x/EE 1.11.x als

Zielversion vorgegeben. Es stellte sich jedoch relativ schnell

heraus, dass hierbei für den Einsatz des Testframeworks

Anpassungen an den Magento-Core-Klassen notwendig

wären. Ab Version CE 1.7.x/EE 1.12.x wurden die

notwendigen Anpassungen bereits von Magento direkt im

Core vorgenommen, was Anpassungen für den Einsatz der

Testsuite überflüssig macht.

Illustration 1: Verzeichnisstruktur Testsuite

3TechDivision GmbH PHPUnit Tests mit Magento

Überarbeitung der Tests

Zu den notwendigen Anpassungen zählten die

Überarbeitung des Bootstrappings, auf das wir später noch

näher eingehen werden, sowie Anpassungen der

eigentlichen Tests, wobei Letzteres aufgrund von

Einschränken in Magento zu den wesentlich aufwändigeren

Arbeiten gehörte.

Aufgrund von Anpassungen der Architektur, hauptsächlich

hinsichtlich Design und Layout, konnten viele Tests aus

Magento 2 nicht 1:1 übernommen werden, da entweder

Verzeichnisse und Dateien schlichtweg nicht vorhanden

waren, Methoden sich geändert hatten, oder gänzlich neu

hinzugekommen waren.

Eine unschöne Einschränkung von Magento hat sich bereits

beim Überarbeiten der Tests gezeigt. So können die

Annotations zum Anlegen von Testdaten (siehe ) in Magento

2 entweder auf Klassen- oder Methodenebene angegeben

werden. Beim Einsatz mit Magento traten hierbei jedoch in

vielen Fällen Probleme hinsichtlich inkonsistenter Testdaten

auf, die wohl auf Anpassungen in Magento 2 im Bereich der

Datenbankschicht hindeuten. Die betroffenen Testfälle

musste bei der Migration entsprechend überarbeitet, also

die entsprechenden Annotationen auf Methodenebene

gesetzt oder gar deaktiviert werden.

Betroffene Testfälle, aktuell ca. 630, wurden nicht gelöscht,

sondern vielmehr geskippt und werden nach und nach

geprüft und überarbeitet. Weiterhin wurden zum Zeitpunkt

der Portierung 27 Testfälle durch Magento als incomplete

deklariert. Auch diese werden, falls sinnvoll, in künftigen

Versionen der Testsuite fertiggestellt.

Anpassen des Bootstrappings

Für das Ausführen der Unit- und der Integrationstest wird

die Testsuite über einen Bootstrapper initialisiert. Der

Bootstrapper wird, wie in Listing 1 dargestellt, in der

PHPUnit-Konfigurationsdatei phpunit.xml.dist registriert, er

initialisiert die Laufzeitumgebung zum Ausführen der

Testsuite.

01

50

<phpunit bootstrap="./framework/bootstrap.php">

...

</phpunit>

Listing 1: Konfiguration PHPUnit Bootstrapper

Im Fall der Unittests werden hier lediglich die Includepfade

gesetzt, der Autoloader initialisiert und das Verzeichnis zur

Speicherung von temporären Dateien geleert.

Für die Integrationstests ist hier wesentlich mehr Aufwand

notwendig, da eine Magento-Sandbox auf Basis der

aktuellen Shopkonfiguration, sowie eine Testdatenbank

erstellt werden muss. Außerdem erweitert Magento PHPUnit

um zusätzliche Profilingmöglichkeiten und einige Observer,

die das Schreiben von Tests für den Entwickler erheblich

vereinfachen.

So stehen über die durch die Testsuite zusätzliche

bereitgestellten Annotations

@magentoAppIsolation

@magentoDataFixture

@magentoConfigFixture

dem Entwickler Funktionen zum automatisierten Anlegen

von Test- und Konfigurationsdaten sowie zur Ausführung

eines einzelnen Tests in einer isolierten (zurückgesetzten)

Instanz zur Verfügung.

4TechDivision GmbH PHPUnit Tests mit Magento

Die Testsuite erzeugt vor dem Ausführen der Tests eine

Sandbox. Hierzu werden alle globalen sowie die in den

Extensions enthaltenen Konfigurationsdateien in ein

temporäres Sandbox-Verzeichnis unterhalb der jeweiligen

Testsuite kopiert. Auf Basis der dort erstellten

Verzeichnisstruktur wird der Shop während des

Bootstrappings initialisiert. Da für die Tests Anpassungen an

den Konfigurationsdateien notwendig sind, stellt dieses

Verfahren sicher, dass für die Ausführung der Tests keinerlei

Veränderungen am Shop vorgenommen und diese

vollkommen isoliert und ohne Nebeneffekte vom Livesystem

ausgeführt werden.

Local- vs. Distributiontesting

Während der Einführungsphase hat sich gezeigt, dass es

aus Zeitgründen in der Praxis nicht möglich ist, bei jedem

lokalen Build alle Tests laufen zu lassen. Auf einem gut

ausgestatteten Entwicklungsrechner dauert der Durchlauf

der gesamten Testsuite einschließlich des Code Coverage

Reports bereits über 15 Minuten. Hinzu kommen noch die

Tests der jeweilige Extension. Für die lokale Entwicklung und

für die Erstellung einer neuen Paketversion steht neben der

Standard-Konfigurationsdatei phpunit.xml.dist, die alle Tests

ausführt (Distributiontesting), noch eine Konfigurationsdatei

phpunit.xml.local zur Verfügung, die nur die Tests im

Namespace der aktuellen Extension ausführt (Localtesting).

Heißt die Extension z. B. TechDivision_GermanTax, so

werden beim Aufruf der Tests unter Verwendung der

Konfigurationsdatei phpunit.xml.local alle Tests unterhalb

des Verzeichnisses dev/tests/integration/testsuite/

TechDivision durchlaufen und der Code Coverage Report

ausschließlich für alle Dateien der jeweiligen Extension

erstellt, was, abhängig von der Anzahl der Tests, zu einer

erheblichen Zeiteinsparung führt.

Schritt 3: Integration in den Entwicklungsprozess

Mit die größte Herausforderung der Portierung war der dritte

und somit letzte Schritt: Die Integration in den

Entwicklungsprozess. Mit Magento 2 werden die Testsuite

und die Tests standardmäßig ausgeliefert. Die Sourcen von

Magento hingegen kommen natürlich ohne Testsuite. Um

eine möglichst nahtlose und einfache Integration zu

gewährleisten, wurden zur lokalen Entwicklung eingesetzte

Magento-Pakete um die Testsuite erweitert. So können die

Tests zum einen über ein ANT-Target jederzeit aus der

lokalen Entwicklungsumgebung heraus gestartet werden,

zum anderen kann beim Build noch vor dem Erstellen des

Pakets sichergestellt werden, dass das Paket erst dann

erstellt wird, wenn alle Tests fehlerfrei durchlaufen wurden.

Hierbei kann der Entwickler durch Aufruf der verschiedenen

ANT-Targets zu jedem Zeitpunkt entscheiden, welche

Testfälle, also Unit- und/oder Integrationstests, ausgeführt

werden sollen. Zusätzlich besteht die Möglichkeit, über Build

Properties zu definieren, ob nur die jeweiligen Tests der

aktuell zu entwickelnden Extension oder zusätzlich auch die

Core Tests ausgeführt werden sollen.

Für den Build- und Deployment Prozess können Tools wie

Phing oder, wie in unserem Fall, ANT verwendet werden.

Zum Ausführen der Test stehen die in Listing 2 aufgeführten

Targets zur Verfügung.

01

02

03

phpunit-run-all-tests

phpunit-run-unit-tests

phpunit-run-integration-tests

Listing 2: ANT Targets zur Ausführung der Unit Tests

Das ANT-Target phpunit-run-integration-tests startet, wie

der Name schon sagt, die Integrationtests der Testsuite. In

der aktuellen Version werden derzeit 1.950 Tests

ausgeführt, wobei davon, wie bereits zuvor beschreiben,

wegen Inkompatibilitäten mit Magento noch 628 geskippt

werden und 27 incomplete sind. Die aktuelle Testsuite mit

2.990 Assertions deckt ca. 11 % der Magento-Core-

Klassen ab, sprich noch knapp 90 % des Magento-

Quelltexts sind nicht durch Tests abgedeckt.

Diese Targets können entweder direkt aus der lokalen

Entwicklungsumgebung oder automatisch während des

Builds durch den CI Server ausgeführt werden. Über die

Build Properties (siehe Listing 3) kann konfiguriert werden,

ob und welche (Distribution oder Local) Tests während des

Builds ausgeführt werden sollen. Zusätzlich kann

konfiguriert werden, welche Datenbank für die Ausführung

der Integrationstest verwendet werden soll, standardmäßig

wird eine zusätzliche leere Datenbank erzeugt.

5TechDivision GmbH

Testen in der Sandbox

PHPUnit Tests mit Magento

Illustration 2: Integrationstests auf Kommandozeile starten

6TechDivision GmbH

Laufen die Tests ohne Fehler durch, wird das Paket erstellt

und automatisch im PEAR Channel hinterlegt.

Selbstverständlich muss nicht zwingend PEAR für das

Paketmanagement verwendet werden, PEAR hat sich

allerdings in den letzten Jahren in unserem Fall bewährt.

Aktuell wird ein Ersatz durch Composer geprüft.

Um sicherzustellen, dass jede Extension für sich selbst,

sowie im Zusammenspiel mit allen anderen Extensions im

Rahmen eines Projekts lauffähig ist, wird pro Extension und

zusätzlich pro Projekt ein eigener Job im CI Server angelegt.

Wird eine Änderung durch den Entwickler in das GIT

Repository der Extension gepusht, wird automatisch durch

den CI Server der Build gestartet, die extensionspezifische

Testsuite ausgeführt und nach erfolgreichem Durchlauf ein

neues PEAR Paket mit der aktuellsten Version gebaut und

auf dem Channel Server zur Verfügung gestellt. Vor dem

Release eines Projekts werden alle Extensions in der

aktuellsten Version installiert und alle Tests – Core und

Extension – ausgeführt. Erst, wenn alle Tests über ein

Projekt erfolgreich durchlaufen, wird das neue Release zum

Deployment freigegeben.

Über das Jenkins Frontend (Illustration 3) haben Scrum

Master und Product Owner bereits während des Sprints die

Möglichkeit, die verschiedene Metriken, sowie die Anzahl

der erstellten Unit- und Integrationstests im Auge zu

behalten. Nach Abschluss des Sprints gewährleisten die

Tests, dass auch bei der Weiterentwicklung der Extension

oder des Shops die Qualität einfach und effektiv

sichergestellt werden kann.

01

02

03

phpunit.tests.execute = false

phpunit.database = ${mysql.database}_tests

phpunit.testsuite = dist

Listing 3: Build Properties zur Konfiguration der ANT-Targets

Illustration 2 zeigt die Ausgabe der Kommandozeile nach

dem Durchlauf der Integrationstests der aktuellen Version

der Testsuite.

PHPUnit Tests mit Magento

Illustration 3: Jenkins Frontend

7TechDivision GmbH

PHPUnit bietet bereits standardmäßig über sogenannte Data Providers [4] die Möglichkeit, einen Test mit unterschiedlichen

Datenstrukturen auszuführen. Hierzu kann über die Annotation @dataProvider eine Methode deklariert werden, die ein Array

oder einen Iterator mit den zu testenden Daten zurückgibt. Die Signatur der zu testenden Methode muss dann analog Listing 4

abhängig von der Datenstruktur die entsprechenden Parameter enthalten.

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

/**

* @dataProvider getHelperDataProvider

*/

public function testGetHelper($inputHelperName, $expectedClass) {

$this->assertInstanceOf($expectedClass, $this->_model->getHelper($inputHelperName));

}

/**

* Data provider to run test with several data sets.

*

* @return void

*/

public function getHelperDataProvier() {

return array(

'class name' => array('core/data', 'Mage_Core_Helper_Data'),

'module name' => array('core', 'Mage_Core_Helper_Data')

);

}

Listing 4: Data Provider per Annotation

Anlegen von Testdaten

PHPUnit Tests mit Magento

8TechDivision GmbH

Speziell für das Ausführen der Integrationstests sind jedoch

fast immer Testdaten notwendig, die sich nicht einfach über

eine CSV-Datei oder ein Array darstellen lassen. Wie bereits

zuvor erwähnt, stellt die Testsuite hierfür über die

zusätzlichen Annotations auf Methodenebene

@magentoDataFixture

@magentoConfigFixture

Funktionen zur Verfügung, mit denen die für jeweiligen Test

erforderlichen Daten bequem angelegt und nach dem Test

automatisch wieder gelöscht werden. Somit ist

sichergestellt, dass die Datenbank vor jedem Test in ihren

Ausgangszustand zurückversetzt wird. Um dies so effizient

wie möglich zu gestalten, werden die über die jeweilige

Annotation spezifizierten Daten im Rahmen einer

Transaktion angelegt, dann der Test ausgeführt und die

Transaktion mit einem Rollback zurückgesetzt. Die

Datenbank wird somit zu keinem Zeitpunkt verändert, da

tatsächlich nie ein Commit für die Transaktion erfolgt.

Für die Annotation @magentoDataFixture muss, wie in

Listing 5 gezeigt, ein relativer Pfad zur Datei ausgehend vom

Basisverzeichnis der jeweiligen Testsuite angegeben

werden, z. B.

01

02

03

04

20

/**

* @magentoDataFixture Mage/Catalog/_files/product_simple.php

*/

public function testSomething() {

}

Listing 5: Annotation zum Anlegen von Testdaten

Innerhalb dieser Skripte kann die Anlage von Testdaten, wie in Listing 6 dargestellt, analog der Implementierung innerhalb

eines Models vorgenommen werden.

01

02

03

04

50

$product = new Mage_Catalog_Model_Product();

$product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE)

->setId(1)

->setAttributeSetId(4)

->save();

Listing 6: Skript zum Anlegen von Testdaten

PHPUnit Tests mit Magento

9TechDivision GmbH

Lokalisierungen

Ein weiteres Problem ergibt sich aufgrund der Lokalisierung von Projekten. Die von Magento erstellte Testsuite für Magento 2

geht, wie in Listing 7 gezeigt, davon aus, dass die Testdatenbank für die USA lokalisiert ist. So wird in diversen Tests auf fest

hinterlegte Werte wie z. B. auf Preise in USD geprüft.

1 $this->assertEquals('<span class="price">$10.00</span>', $this->_model->getFormatedPrice());

Listing 7: Fest hinterlegte Werte in Magento 2 Tests

Nachdem Extensions wie z. B. TechDivision_GermanTax über die Installations- und Datenskripte die Lokalisierung der

Datenbank entsprechend anpassen, schlagen diese Tests fehl. Um dieses Problem zu lösen, müssen, wie in Listing 8 gezeigt,

die fest hinterlegten Werte entsprechend der im jeweiligen Shop konfigurierten Locale lokalisiert und erst dann geprüft werden.

01

02

$formattedPrice = Mage::app()->getStore()->formatPrice(0.00, false);

$this->assertEquals('<span class="price">' . $formattedPrice . '</span>', $this->_model->getFormatedPrice());

Listing 8: Auf lokalisierte Werte testen

Beim Einsatz der Testsuite im täglichen Entwicklungsprozess

hat sich eine Vielzahl von Problemen gezeigt, die ohne deren

Einsatz nicht auffallen würden. Während der Überarbeitung

hat sich gezeigt, dass sich die Entwickler der Testsuite, auf

jeden Fall bis zum Zeitpunkt der Portierung, noch nicht mit

allen Aspekten des Testens auseinandergesetzt hatten.

Nachfolgend möchte ich auf die, aus meiner Sicht, größten

Probleme bei der Portierung etwas detaillierter eingehen.

Aufteilung von Installations- und Datenskripten

So werden z. B. häufig die Installations- und Datenskripte

nicht entsprechend den von Magento gemachten Vorgaben

– Installationskripte im Verzeichnis sql, Datenskripte im

Verzeichnis data – getrennt abgelegt. Erfolgt keine

Trennung, so kommt es, da Magento im ersten Schritt nur

die Tabellen anlegt und keine Daten einspielt, bei Erstellung

der Testdatenbank durch die Testsuite zu Fehlern. So treten

z. B. bei Installation einer Extension ohne diese Trennung,

bei der Verknüpfungen der Daten zur Steuertabelle angelegt

werden sollen, zwangsläufig CONSTRAINT-Probleme auf,

da die Steuerdaten zu diesem Zeitpunkt eben aufgrund der

Trennung noch nicht existieren.

Die Trennung in Installations- und Datenskripten alleine trägt

zwar an sich bereits zur Vermeidung von Problemen bei,

reicht jedoch noch nicht aus. Zusätzlich ist es zwingend

erforderlich, in der entsprechenden Konfigurationsdatei

unter app/etc/modules Abhängigkeiten zu anderen

Extensions, auch zu Core-Modulen, zu hinterlegen. Anhand

dieser Abhängigkeiten wird bei der Installation der

Testdatenbank durch die Testsuite die Reihenfolge, in der

die Installations- und Datenskripte ausgeführt werden,

festgelegt. Nur so kann sichergestellt werden, dass eine

benötigte Tabelle oder deren Daten vor dem Ausführen des

Installations- oder Datenskripts auch tatsächlich vorhanden

ist.

Probleme beim Einsatz der Testsuite

PHPUnit Tests mit Magento

10TechDivision GmbH

Integration von Drittanbieter-Extensions

DER FOLGENDE SATZ IST AUCH KAPUTT, DAS MIT DEM

NEBEN FUNKTIONIERT SO NICHT Neben Abhängigkeiten von

Extensions hat sich im Laufe der Einführung gezeigt, dass

bei der Integration von Drittanbieter-Extensions die Magento

Core Tests in vielen Fällen fehlschlagen, da diese durch das

Überschreiben von Core-Klassen die ursprüngliche

Funktionalität verändern. Grundsätzlich lässt sich diese

Problem auf drei Arten lösen.

Die erste und beste Möglichkeit ist natürlich der gänzliche

Verzicht auf Rewrites, das Problem stellt sich somit gar nicht

erst.

Die zweite Möglichkeit, die immer dann verwendet werden

sollte, wenn die Verwendung eines Rewrites unumgänglich

ist, erlaubt dem Entwickler, die Extension per Konfiguration

über die Systemsteuerung zu aktivieren. Die Core Tests

schlagen somit nicht fehl, da die Extension zuerst über die

Annotation @magentoConfigFixture aktiviert werden muss.

Die dritte und letzte Möglichkeit erlaubt dem Entwickler,

einen Core Test durch die zusätzlich eingeführte Annotation

@magentoRewriteTestMethod zu ersetzten. So würde die

Methode des in Listing 9 gezeigten DocBlocks z. B. den

Core Test MageTest::testGetModel() ersetzen.

Abhängigkeiten von Extensions

Lokalisierung und Drittanbieter-Extensions stellen sicherlich

nicht zu unterschätzende Probleme dar, die jedoch relativ

leicht in den Griff zu bekommen sind. Als deutlich

komplizierteres Problem hat sich die Abhängigkeit von

Extensions beim Ausführen der Testsuite gezeigt.

Abhängigkeiten zum Magento Core spielen natürlich nur

eine untergeordnete Rolle (siehe ). Hat eine Extension jedoch

eine oder gar mehrere Abhängigkeit zu anderen oder

Drittanbieter-Extensions, so müssen beim Aufruf der

Testsuite diese ebenfalls vorhanden sein. Magento hat zwar

einen Mechanismus, einer Extension mitzuteilen, dass diese

von einer oder mehreren anderen abhängig ist, allerdings

werden bei der Installation abhängige Extensions nicht

automatisch mitinstalliert. Die Lösung dieses Problems ist in

diesem Fall abhängig vom eingesetzten Buildtool und vom

Paketmanagement, in unserem Fall also ANT und PEAR [5].

Für jedes PEAR-Paket lassen sich Abhängigkeiten

definieren, die bei der Installation sicherstellen, dass

benötigte Pakete auf jeden Fall vorhanden sind.

Beim Aufruf eines der ANT Targets (siehe ) zum Ausführen

der Testsuite wird, falls nicht bereits vorhanden,

automatisiert eine neue Magento-Instanz angelegt und ein

für jede Instanz separater PEAR Channel initialisiert.

Anschließend wird lokal ein PEAR-Paket aus der aktuellsten

Version der Sourcen erzeugt und über den zuvor

initialisierten PEAR Channel installiert. Benötigt das Paket

andere Pakete, so werden diese über die im PEAR-Paket

definierten Abhängigkeiten ebenfalls mitinstalliert. Somit

wird vor dem Aufruf der Testsuite eine konsistente

Testumgebung aufgebaut, die sicherstellt, dass alle zur

Ausführung der Tests benötigten Sourcen in der Testinstanz

vorhanden sind.

Vielleicht haben Sie sich zuvor gefragt, warum wir auch

Drittanbieter-Extensions im Rahmen von Projekten in

unseren Build- und Deploymentprozess integrieren. Die

Antwort darauf lautet, dass in vielen Projekten aus Effizienz-

und Konstengründen Drittanbieter-Extensions verwendet

werden, deren Funktionalität jedoch fast immer erweitert

werden muss. In den meisten Fällen wird hierzu, eine

weitere, abhängige Extension implementiert, um bei einem

Update der Extension Probleme zu vermeiden. Wie zuvor

beschrieben, ist es für den Einsatz der Testsuite notwendig,

die Drittanbieter-Extension ebenfalls zu installieren, genau

das lässt sich jedoch nur erreichen, wenn diese auch in den

eigenen Build- und Deploymentprozess integriert ist.

01

02

03

04

...

20

/**

* @magentoRewriteTestMethod MageTest::testGetModel()

*/

public function testGetModel() {

...

}

Listing 9: Ersetzen eines Core Tests

PHPUnit Tests mit Magento

11TechDivision GmbH

Links & Literatur

[1] https://wiki.magento.com/display/MAGE2DOC/Magento+Automated+Testing+Guide

[2] http://www.phpunit.de

[3] http://ant.apache.org

[4] http://www.phpunit.de/manual/3.6/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers

[5] http://pear.php.net

[6] http://www.github.com/techdivision/TechDivision_MagentoUnitTesting

Trotz der aktuell noch relativ geringen Testabdeckung, hat

bereits die Einführung der Testsuite zu einer erheblichen

Verbesserung der Qualität beigetragen. So konnten schon

während der Migration zahlreiche im herkömmlichen Betrieb

nicht sichtbare Probleme erkannt und beseitigt werden.

Durch die Einführung und die tägliche Arbeit mit der

Testsuite und die Umstellung auf SCRUM wurden die

Entwickler fast über Nacht zur Änderung ihrer Arbeitsweise

hin zu TDD gezwungen. Hierdurch entstanden zwar im

ersten Schritt zusätzliche Aufwände in Form von

Einarbeitung, Workshops und dem Schreiben von Tests,

jedoch zeigt sich bereits nach kurzer Zeit, dass die Qualität

und damit auch die Kundenzufriedenheit proportional zu den

Aufwänden steigt.

Der aktuelle Stand der Testsuite kann über das Github

Repository [6] der TechDivision GmbH heruntergeladen und

kostenfrei in eigenen Projekte eingesetzt werden. Da aus

Kompatibilitätsgründen derzeit noch zahlreiche Tests

deaktiviert wurden, freuen wir uns natürlich über

Unterstützung aus der Community, um alle sinnvollen Tests

aus Magento 2 zu portieren und eine möglichst große

Testabdeckung zu erreichen.

Fazit

Über uns:TechDivision ist ein etablierter E-Commerce Solution Partner und unterstützt seit vielen Jahren nationale und internationale Kunden in der integrierten Planung, Design und Implementierung von komplexen E-Commerce-Lösungen. Als Magento Gold Partner von Anfang an, gehört TechDivision zu den führenden Magento Solution Partner in Europa. Mittelgroße Kunden und internationale Unternehmen wie WMF oder Ritter-Sport, vertrauen in die Kompetenz und Erfahrung von TechDivision. Derzeit hat TechDivision zwei Standorte in Rosenheim / Kolbermoor und München.

Weitere Informationen über TechDivision: www.techdivision.com

TechDivision GmbH

Spinnereiinsel 3a83059 Kolbermoor

Telefon +49 8031 2210 55 - 0Telefax +49 8031 2210 55 - 22

Redaktionell Verantwortlicher: Josef Willkommer

E-Mail: [email protected]

www.techdivision.com

PHPUnit Tests mit Magento