Lorsque j'écris mes modules, j'essaie de leur fournir des tests unitaires pour les parties les plus critiques de l'application. Cependant, il existe actuellement (Magento 2.1.3) plusieurs façons d'écrire des tests unitaires:
Différentes façons de tester
- Intégrez-le avec
bin/magento dev:tests:run unit
et exécutez-le au-dessus des paramètres phpunit par défaut fournis avec Magento. - Écrivez-les séparément, exécutez-les avec
vendor/bin/phpunit app/code/Vendor/Module/Test/Unit
et moquez tout ce qui est Magento. - Écrivez-les séparément, simulez tout et utilisez une version globale de PHPUnit.
- Écrivez-les séparément, exécutez-les avec
vendor/bin/phpunit
, mais utilisez toujours\Magento\Framework\TestFramework\Unit\Helper\ObjectManager
.
Magento 2 et PHPUnit
En plus de cela, Magento 2 est livré avec PHPUnit 4.1.0, qui n'est pas compatible PHP7. Les natifs avec indication de type (comme string
et `int) et la déclaration des types de retour dans vos signatures génèreront des erreurs. Par exemple, une interface / classe avec une signature de méthode comme celle-ci:
public function foo(string $bar) : bool;
... ne pourra pas être raillé par PHPUnit 4.1.0. :-(
Ma situation actuelle
C'est à cause de cela que j'écris maintenant principalement mes tests unitaires de la troisième manière (en appelant une version PHPUnit globale du système).
Dans ma configuration, j'ai PHPUnit 5.6 installé à l'échelle mondiale, donc je peux résoudre l'écriture de code PHP7 approprié, mais je dois faire quelques ajustements. Par exemple:
phpunit.xml
doit ressembler à ceci pour que je puisse utiliser l'autochargeur du compositeur:
<?xml version="1.0"?>
<phpunit bootstrap="../../../../../../vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="Testsuite">
<directory>.</directory>
</testsuite>
</testsuites>
</phpunit>
... et dans toutes mes setUp()
méthodes, j'ai la vérification suivante pour pouvoir écrire mes tests avec la compatibilité ascendante:
// Only allow PHPUnit 5.x:
if (version_compare(\PHPUnit_Runner_Version::id(), '5', '<')) {
$this->markTestSkipped();
}
De cette façon, lorsque mes tests sont exécutés par PHPUnit intégré à Magentos, cela ne génère pas d'erreur.
Ma question
Voici donc ma question: est-ce une façon «saine» d'écrire des tests unitaires? Parce qu'il ne me semble pas juste que Magento soit livré avec tout un tas d'outils pour aider aux tests et je ne peux pas les utiliser parce que j'utilise PHP7. Je sais qu'il existe des tickets sur GitHub qui résolvent ce problème, mais je me demande comment la communauté écrit actuellement ses tests.
Existe-t-il un moyen d'écrire des tests unitaires dans Magento 2 afin que je n'aie pas à «rétrograder» mon code et que je puisse toujours utiliser les assistants intégrés de Magentos pour se moquer de tout ce que le gestionnaire d'objets touche? Ou est-ce même une mauvaise pratique d'utiliser le gestionnaire d'objets même dans vos tests unitaires?
Il me manque beaucoup de conseils / d'exemples sur la manière appropriée de tester à l'unité vos propres modules personnalisés.
la source
Réponses:
L'utilisation de la version PHPUnit fournie, même si elle est ancienne, est probablement la meilleure solution, car cela permettra d'exécuter les tests de tous les modules ensemble pendant le CI.
Je pense que l'écriture de tests d'une manière incompatible avec le cadre de test fourni réduit considérablement la valeur des tests.
Bien sûr, vous pouvez configurer CI pour exécuter vos tests avec une version différente de PHPUnit, mais cela ajoute beaucoup de complexité au système de construction.
Cela dit, je suis d'accord avec vous qu'il ne vaut pas la peine de prendre en charge PHP 5.6. J'utilise les indications de type scalaire PHP7 et les indications de type retour autant que possible (en plus, je ne me soucie pas de la place de marché).
Afin de contourner les limitations de la bibliothèque de simulation PHPUnit 4.1, il existe au moins deux solutions de contournement assez simples que j'ai utilisées dans le passé:
Utilisez des classes anonymes ou régulières pour créer vos doubles de test, par exemple
Utilisez le PHPUnit fourni mais une bibliothèque de simulation tierce qui peut être incluse via composer avec
require-dev
, par exemple https://github.com/padraic/mockery . Toutes les bibliothèques de simulation que j'ai essayées peuvent très facilement être utilisées avec n'importe quel framework de test, même une très ancienne version de PHPUnit comme 4.1.Aucun de ceux-ci n'a d'avantage technique sur l'autre. Vous pouvez implémenter n'importe quelle double logique de test requise avec l'une ou l'autre.
Personnellement, je préfère utiliser des classes anonymes car cela n'ajoute pas au nombre de dépendances externes, et c'est aussi plus amusant de les écrire de cette façon.
EDIT :
Pour répondre à vos questions:
Oui, voir l'exemple ci-dessous.
L'utilisation de classes anonymes pour créer des doubles de test est également une "simulation", ce n'est pas vraiment différent de l'utilisation d'une bibliothèque de simulation telle que PHPUnits ou Mockery ou autre.
Une maquette est juste sur un type spécifique de test double , quelle que soit la façon dont elle est créée.
Une petite différence entre l'utilisation de classes anonymes ou d'une bibliothèque de simulation est que les classes anonymes n'ont pas de dépendance de bibliothèque externe, car il s'agit simplement de PHP. Sinon, il n'y a ni avantages ni inconvénients. C'est simplement une question de préférence. Je l'aime parce qu'il illustre que les tests ne concernent pas un framework de test ou une bibliothèque de simulation, les tests consistent simplement à écrire du code qui exécute le système testé et valide automatiquement son fonctionnement.
Cela peut être problématique car les tests dans d'autres modules et le noyau ne sont testés qu'avec PHPUnit 4.1, et en tant que tel, vous pouvez rencontrer de faux échecs dans CI. Je pense qu'il est préférable de s'en tenir à la version intégrée de PHPUnit pour cette raison. @maksek a déclaré qu'ils mettront à jour PHPUnit, mais il n'y a pas d'ETA pour cela.
Exemple de test avec un double test d'une classe qui nécessite PHP7 s'exécutant avec PHPUnit 4.1, en utilisant la bibliothèque Mockery:
la source
composer.json
fichier principal vers 5.3.5 (la dernière version prenant en charge PHP7 et ayant des méthodes de simulation publiques (requises par les propres tests de Magento 2))? Tant de questions maintenant ...À l'heure actuelle, Magento 2 prend en charge les prochaines versions de PHP:
Cela signifie que tout le code écrit par l'équipe Magento fonctionne sur toutes les versions prises en charge.
Par conséquent, Magento Team n'utilise pas uniquement les fonctionnalités de PHP 7. Les fonctionnalités de PHP 5.6 peuvent être couvertes par PHPUnit 4.1.0.
En écrivant votre propre code, vous pouvez faire tout ce que vous voulez et écrire des tests comme vous le souhaitez. Mais je pense que vous ne pourrez pas publier votre extension sur Magento Marketplace en raison d'une violation des exigences.
la source