Einfache UnitTests für Magento

Seit nun knapp fünf Monaten stelle ich mich der Herausforderung saubere Softwareentwicklung und Magento in Einklang zu bringen. Ein kleiner Schritt in diese Richtung war der Einsatz von UnitTests, um mögliche Fehler während der Entwicklung schneller zu finden.

Viele Fehler treten bei Magento schon durch eine fehlerhafte Konfiguration auf, was zur Folge haben kann, dass wir keine Instanz unser lokalisierten Klasse bekommen, sondern ein standard Magento-Objekt oder einen Fehler, weil keine passende Klasse gefunden wird.

So habe ich also angefangen, die Existenz der zu prüfenden Klassen zu testen und ob die Mage-Factory das gewünschte Objekt zurück gibt. Bei einigen Klassen ist es zudem auch noch wichtig, dass sie von der richtigen Elternklasse abgeleitet sind.

Da sich diese Tests immer wiederholten, zeichnete sich schnell ein Muster ab. Ebenso erfolgt auch die Namesgebung der Magentoklassen nach einem gewissen Muster. Was wäre also naheliegender, als beides miteinander zu verbinden und so in Zukunft eine Menge unnützer Schreibarbeit zu sparen?

Als erstes habe ich dafür einen erweiteren TestCase vom PHPUnit-TestCase abgeleitet, der mir weitere vereinfachte Asserts zur Verfügung stellt und die Tests dadurch auch etwas lesbarer macht.

$this->assertClassExists($classname);

statt

$this->assertTrue(class_exists($classname));

Auf diesem Wege lassen sich dann auch z.B. Getter und Setter einfach auf das gewünschte Standardverhalten prüfen.

Im nächsten Schritt habe ich einen Entity-TestCase abgeleitet, der als Basis für alle weiteren TestCases für Models, Blocks und Helper dienen soll. Dieser ist in sich schon ein wenig intelligenter und erkennt anhand des Namens der Test-Klasse, welche Klasse getestet werden soll, welchen Typ diese hat und welche die Standard-Elternklasse ist.

Diese Informationen werden, nebenbei bemerkt, durch protected Methoden ermittelt und könnten zu jeder Zeit durch noch speziellere TestCases wieder überschrieben werden.

Mit den nun vorliegenden Informationen ist diese TestCase-Klasse mächtig genug, um alleine durch Vererbung die grundlegenden Tests durchzuführen.

Für die jeweiligen Typen, z.B. Model habe ich dann noch weitere TestCases abgeleitet, um dort noch spezielle Methoden implementieren zu können.

Ein sehr einfacher Test für die Model-Klasse “Mein_Customer_Model_Customer” sähe dann beispielsweise so aus:

class Mein_Customer_Model_CustomerTest extends Mein_Model_TestCase
{
}

Dadurch würde nun automatisch getestet werden, ob der Autoloader die Klasse “Mein_Customer_Model_Customer” finden kann, diese von der Magento-Model-Klasse erbt und ob die Factory aufgrund der Konfiguration auch das richtige Objekt liefert.

Ich denke, dass es viel einfacher nicht mehr geht und das Argument gegen Tests damit dann auch aus der Welt sein sollte.

Kleiner Tipp: Wenn man es nun noch etwas konfortabler mag, dann kann man sich seine Models auch mit dem Zend_CodeGenerator bauen lassen und die Tests gleich mit.

3 Kommentare

  1. Kannste die Tests evtl. zur Verfügung stellen?

  2. Na mal sehen was sich da machen lässt.

  3. Pingback: Schmerzfreier Einsatz von UnitTests – ebene7

Schlagwörter: Adapter, Amazon, Animation, Annotations, Anonyme Klasse, Ant, Apache, API, Array, ArrayAccess, Attachment, AutoLoader, Bedienung, Bedingung, Benchmark, Bildbearbeitung, BOM, Bootstrap, Bot, Byte Order Mark, Callback, CamelCase, Canvas, Captcha, Cheatsheet, CLI, Closure, Cloud, CodeSniffer, Community, Comparator, Contest, Controller, Converter, CouchDB, Countable, Cronjob, CSV, CustomLibrary, Custom_Model, Data Mapper, Datei, Datenbank, Datenstruktur, Datentypen, Dating, Decorator, Dekorierer, Design Patterns, Dump, Duplikat, each, Eclipse, Entwicklung, Entwurfsmuster, Enum, Erweiterung, Eventhandling, Exception-Handling, Extension, Factory, Fehler, Flash, Foreach, Formatierung, Formular, Funktion, Futon, Header, HTML5, HTTP, IDE, If, Implementierung, InnoDB, Interceptor, Interface, isset, Iterator, Java, JavaScript, jQuery, Konfiguration, Konsole, Kontrollstruktur, kopieren, Late Static Binding, Layout, Linux, Listeners, Logging, Löschen, Magento, Magic Methods, Marketing, Methode, Model, MVC, MySQL, NetBeans, Objekt, Observable, Observer, OOP, Operator, Parameter, Partnersuche, Performance, PHP, phpMyAdmin, PHPUnit, Plugin, Proxy, Qualitätssicherung, Query, Reflection, Request, Response, Rest-API, Rockstar, Routing, S3, Samba, Scheifen, Schleife, Schutz, Secure Shell, Selbstreferenz, Shop, Sicherheit, Sicherung, Singleton Pattern, SOAP, Sortierung, Sourcecode, Spam, Speicherproblem, Spickzettel, SPL, SSH, Statement, Stellvertreter, Strategy Pattern, Stream, String, Sun VirtualBox, Support, Switch, Symfony, Symfony2, Symfony Live, Tag, Template, Template Method, Ternär Operator, Testing, Thumbnail, Tool, Tour, Twig, Type-Cast, Umwandlung, Underscore, unset, Vererbung, Verzweigung, Video, Videospiel, Virtualisierung, Visitor Pattern, Vorschaubild, walk, Webserver, Webservice, Weiterleitung, Wrapper, Youtube, Zeitsteuerung, Zend Framework, Zend_Cloud, Zend_CodeGenerator, Zend_Http_Client, Zend_Service, Zugriffsmethode