Concentrer vos tests sur le domaine. Un exemple PHPUnit
Oct 05, 2024 am 06:07 AMIntroduction
Souvent, les développeurs essaient de tester 100 % (ou presque 100 %) de leur code. Apparemment, c'est l'objectif que chaque équipe devrait atteindre pour ses projets mais, de mon point de vue, une seule partie de l'ensemble du code devrait être entièrement testée : votre domaine.
Le domaine est, essentiellement, la partie de votre code qui définit ce que fait réellement le projet. Par exemple, lorsque vous conservez une entité dans la base de données, votre domaine n'est pas chargé de la conserver dans la base de données, mais de s'assurer que les données conservées ont un sens selon votre modèle économique. Il est possible que lorsque vous enregistrez vos données dans la base de données, vous utilisiez une bibliothèque externe comme PHP Doctrine. Cette bibliothèque est déjà entièrement testée, il n'est pas nécessaire de tester ce qu'elle fait. Si vous transmettez à Doctrine les données correctes, elles seront enregistrées dans la base de données sans problème.
L'exemple présenté dans les sections suivantes n'essaie pas de montrer comment fonctionne le Domain Driven Design, il existe de nombreux articles qui l'expliquent très bien. Je vais essayer de montrer comment avoir votre domaine bien défini et découplé peut vous aider à tester facilement et en vous concentrant sur ce que fait votre application.
L'exemple est construit sur un environnement Symfony et en utilisant la bibliothèque PHPUnit, mais l'idée est valable pour n'importe quel langage ou framework.
Le code à tester
Imaginons que notre application se connecte à une API externe qui renvoie des données sur la probabilité de pluie pour une date spécifiée. Les données renvoyées ressemblent à ceci :
{ "date" : "2022-12-01", "rain_probability" : 0.75 }
Maintenant, nous devons prendre ces données et les classer selon cette cartographie :
- rain_probability < 0.40 : FAIBLE
- rain_probability ≥ 0,40 && rain_probability < 0,75 : MOYEN
- probabilité_pluie ≥ 0,75 : ÉLEVÉE
et enregistrez le résultat sur une table de base de données décrite par l'entité suivante :
#[ORM\Entity(repositoryClass: RainMeasure::class)] class RainMeasure { #[ORM\Column] private string $date; #[ORM\Column] private float $probability; #[ORM\Column(length: 10)] private string $label; // Getters and setters // ....... }
Créons un gestionnaire qui récupère les données de l'API externe, définit l'étiquette en fonction de la probabilité de pluie et l'enregistre dans la base de données.
class RainMeassureHandler { private EntityManagerInterface $em; public function __construct(EntityManagerInterface $em) { $this->em = $em; } public function saveMeasure(array $measureData): void { if($measureData['rain_probability'] < 0.40){ $label = 'LOW'; } elseif ($measureData['rain_probability'] >= 0.40 && $measureData['rain_probability'] < 0.75){ $label = 'MEDIUM'; } else{ $label = 'HIGH'; } $rainMeasure = new RainMeassure(); $rainMeasure->setDate($measureData['date']); $rainMeasure->setProbability($measureData['rain_probability']); $rainMeasure->setLabel($label); $this->em->persist($rainMeasure); $this->em->flush(); } } <p>Si nous essayons de créer un test pour le gestionnaire ci-dessus, nous constaterons que nous devrons injecter l'<strong>EntityManagerInterface</strong> puisque le comportement que nous voulons tester (définir une étiquette en fonction de la valeur de probabilité) est couplé dans le même gestionnaire qui enregistre le résultat dans la base de données. Nous pourrions essayer de charger l'<strong>EntityManagerInterface</strong> à l'aide de mocks et de stubs mais est-ce nécessaire ?. Évidemment non. Comme dit précédemment, nous devrions essayer de nous concentrer sur le test du comportement qui appartient à notre domaine, c'est-à-dire obtenir la bonne étiquette en fonction de la probabilité de pluie.</p> <h2> Comportement de découplage que nous voulons tester </h2> <p>Afin de simplifier notre test, nous allons déplacer le comportement que nous souhaitons tester vers une autre classe :</p> <pre class="brush:php;toolbar:false"> class RainMeasureLabelHandler { public function getLabelFromProbability(float $prob): string { if($prob < 0.40){ $label = 'LOW'; } elseif ($prob >= 0.40 && $prob < 0.75){ $label = 'MEDIUM'; } else{ $label = 'HIGH'; } return $label; } }
Et maintenant, notre RainMeassureHandler ressemblera à ceci :
class RainMeasureHandler { private EntityManagerInterface $em; public function __construct(EntityManagerInterface $em) { $this->em = $em; } public function saveMeasure(array $measureData): void { $rainMeasureLabelHandler = new RainMeasureLabelHandler(); $label = $rainMeasureLabelHandler->getLabelFromProbability($measureData['rain_probability']); $rainMeasure = new RainMeasure(); $rainMeasure->setDate($measureData['date']); $rainMeasure->setProbability($measureData['rain_probability']); $rainMeasure->setLabel($label); $this->em->persist($rainMeasure); $this->em->flush(); } }
Nous pouvons maintenant nous concentrer sur le test de notre RainMeasureLabelHandler qui ferait partie de notre domaine et n'aurait aucune dépendance vis-à-vis des couches externes. Le tester serait aussi simple que indiqué :
Conclusion
Je voudrais dire que d’autres types de tests seraient également utiles. Peut-être avons-nous une API et souhaitons-nous tester les entrées et les sorties avec un environnement de test qui comprend une base de données et d'autres ressources dont nous pourrions avoir besoin. Mais n'oubliez pas de faire découpler votre domaine et de le tester entièrement.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Article chaud

Outils chauds Tags

Article chaud

Tags d'article chaud

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

11 meilleurs scripts de raccourcissement d'URL PHP (gratuit et premium)

Travailler avec les données de session Flash dans Laravel

Misque de réponse HTTP simplifié dans les tests Laravel

Construisez une application React avec un Laravel Back End: Partie 2, React

Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST

12 meilleurs scripts de chat PHP sur Codecanyon
