Wenn ich meine Module schreibe, versuche ich, ihnen Komponententests für die kritischsten Teile der Anwendung zur Verfügung zu stellen. Es gibt jedoch im Moment (Magento 2.1.3) verschiedene Möglichkeiten, um Unit-Tests zu schreiben:
Verschiedene Testmethoden
- Integrieren Sie es in
bin/magento dev:tests:run unit
und führen Sie es über die mit Magento mitgelieferten phpunit-Standardeinstellungen aus. - Schreiben Sie sie separat, führen Sie sie mit aus
vendor/bin/phpunit app/code/Vendor/Module/Test/Unit
und verspotten Sie alles, was Magento ist. - Schreiben Sie sie separat, verspotten Sie alles und verwenden Sie eine systemweite Version von PHPUnit.
- Schreiben Sie sie separat, führen Sie sie mit aus
vendor/bin/phpunit
, aber nutzen Sie sie trotzdem\Magento\Framework\TestFramework\Unit\Helper\ObjectManager
.
Magento 2 und PHPUnit
Außerdem wird Magento 2 mit PHPUnit 4.1.0 ausgeliefert, das nicht PHP7-kompatibel ist. Indem Sie Eingeborene (wie string
und `int) mit Typhinweisen versehen und Rückgabetypen in Ihren Signaturen deklarieren, werden Fehler ausgegeben. Zum Beispiel eine Schnittstelle / Klasse mit einer Methodensignatur wie folgt:
public function foo(string $bar) : bool;
... kann von PHPUnit 4.1.0 nicht verspottet werden. :-(
Meine aktuelle Situation
Aus diesem Grund schreibe ich meine Unit-Tests jetzt hauptsächlich auf die dritte Art und Weise (durch Aufrufen einer system-globalen PHPUnit-Version).
In meinem Setup habe ich PHPUnit 5.6 global installiert, damit ich den richtigen PHP7-Code schreiben kann, aber ich muss einige Verbesserungen vornehmen. Beispielsweise:
phpunit.xml
muss so aussehen, damit ich den Composer-Autoloader verwenden kann:
<?xml version="1.0"?>
<phpunit bootstrap="../../../../../../vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Testsuite">
<directory>.</directory>
</testsuite>
</testsuites>
</phpunit>
... und in all meinen setUp()
Methoden habe ich folgende Prüfung, damit ich meine Tests mit Aufwärtskompatibilität schreiben kann:
// Only allow PHPUnit 5.x:
if (version_compare(\PHPUnit_Runner_Version::id(), '5', '<')) {
$this->markTestSkipped();
}
Auf diese Weise wird kein Fehler ausgegeben, wenn meine Tests von Magentos 'eingebautem PHPUnit ausgeführt werden.
Meine Frage
Hier ist meine Frage: Ist dies eine "gesunde" Art, Komponententests zu schreiben? Weil es mir nicht richtig erscheint, dass Magento mit einer ganzen Reihe von Tools zum Testen geliefert wird und ich sie nicht verwenden kann, weil ich PHP7 verwende. Ich weiß, dass es auf GitHub Tickets gibt, die dieses Problem beheben, aber ich frage mich, wie die Community derzeit ihre Tests schreibt.
Gibt es eine Möglichkeit, in Magento 2 Komponententests zu schreiben, damit ich meinen Code nicht 'downgraden' muss und trotzdem die integrierten Hilfsprogramme von Magentos verwenden kann, um alles zu verspotten, was der Objektmanager berührt? Oder ist es sogar eine schlechte Übung, den Objektmanager auch in Ihren Unit-Tests zu verwenden?
Ich vermisse viele Anleitungen / Beispiele, wie Sie Ihre eigenen benutzerdefinierten Module testen können.
quelle
Antworten:
Die Verwendung der mitgelieferten PHPUnit-Version ist wahrscheinlich der beste Weg, auch wenn sie älter ist, da dann die Tests für alle Module zusammen während der CI ausgeführt werden können.
Ich denke, das Schreiben von Tests auf eine Weise, die mit dem gebündelten Testframework nicht kompatibel ist, verringert den Wert der Tests erheblich.
Natürlich können Sie CI so einrichten, dass Ihre Tests mit einer anderen Version von PHPUnit ausgeführt werden. Dies erhöht jedoch die Komplexität des Build-Systems.
Trotzdem stimme ich Ihnen zu, dass es sich nicht lohnt, PHP 5.6 zu unterstützen. Ich verwende so oft wie möglich PHP7-Skalartyphinweise und Rückgabetyphinweise (außerdem ist mir der Marktplatz egal).
Um die Einschränkungen der PHPUnit 4.1-Verspottungsbibliothek zu umgehen, gibt es mindestens zwei einfache Problemumgehungen, die ich in der Vergangenheit verwendet habe:
Verwenden Sie zum Beispiel anonyme oder reguläre Klassen, um Ihre Test-Doubles zu erstellen
Verwenden Sie die mitgelieferte PHPUnit, aber eine Spottbibliothek eines Drittanbieters, die über Composer eingebunden werden kann
require-dev
, beispielsweise mit https://github.com/padraic/mockery . Alle versuchten spottenden Bibliotheken können sehr einfach mit jedem Testframework verwendet werden, selbst mit einer sehr alten Version von PHPUnit wie 4.1.Keines davon hat einen technischen Vorteil gegenüber dem anderen. Sie können jede erforderliche Testdoppellogik mit einem der beiden implementieren.
Persönlich bevorzuge ich die Verwendung anonymer Klassen, da dies nicht zur Anzahl externer Abhängigkeiten beiträgt und es auch mehr Spaß macht, sie auf diese Weise zu schreiben.
EDIT :
Um Ihre Fragen zu beantworten:
Ja, siehe folgendes Beispiel.
Die Verwendung anonymer Klassen zum Erstellen von Test-Doubles ist ebenfalls "spöttisch". Sie unterscheidet sich nicht wirklich von der Verwendung einer Spottbibliothek wie PHPUnits oder Mockery oder einer anderen.
Ein Mock bezieht sich nur auf einen bestimmten Testdoppeltyp , unabhängig davon, wie er erstellt wird.
Ein kleiner Unterschied zwischen der Verwendung anonymer Klassen oder einer spöttischen Bibliothek besteht darin, dass anonyme Klassen keine Abhängigkeit von externen Bibliotheken aufweisen, da es sich nur um einfaches PHP handelt. Ansonsten gibt es keine Vor- oder Nachteile. Es ist einfach eine Frage der Präferenz. Ich mag es, weil es zeigt, dass es beim Testen nicht um ein Testframework oder eine Spottbibliothek geht. Beim Testen wird nur Code geschrieben, der das zu testende System ausführt und dessen Funktion automatisch überprüft.
Dies kann problematisch sein, da die Tests in anderen Modulen und im Core nur mit PHPUnit 4.1 getestet werden und Sie daher möglicherweise auf falsche Fehler in CI stoßen. Ich denke, es ist aus diesem Grund am besten, sich an die mitgelieferte Version von PHPUnit zu halten. @maksek sagte, sie werden PHPUnit aktualisieren, aber es gibt keine ETA dafür.
Beispiel für einen Test mit einem Test Double einer Klasse, für die PHP7 mit PHPUnit 4.1 unter Verwendung der Mockery-Bibliothek ausgeführt werden muss:
quelle
composer.json
auf 5.3.5 (die neueste Version, die PHP7 unterstützt, und öffentliche Verspottungsmethoden (erforderlich für Magento 2-eigene Tests))? So viele weitere Fragen jetzt ...Momentan unterstützt Magento 2 folgende PHP-Versionen:
Dies bedeutet, dass der gesamte von Magento Team geschriebene Code auf jeder unterstützten Version funktioniert.
Daher verwendet Magento Team nicht nur PHP 7-Funktionen. PHP 5.6-Funktionen können mit PHPUnit 4.1.0 abgedeckt werden.
Wenn Sie Ihren eigenen Code schreiben, können Sie alles tun, was Sie wollen, und Tests schreiben, wie Sie möchten. Ich bin jedoch der Meinung, dass Sie Ihre Erweiterung aufgrund von Verstößen gegen die Anforderungen nicht auf Magento Marketplace veröffentlichen können.
quelle