Maison développement back-end tutoriel php Concentrer vos tests sur le domaine. Un exemple PHPUnit

Concentrer vos tests sur le domaine. Un exemple PHPUnit

Oct 05, 2024 am 06:07 AM

Introduction

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
}


Copier après la connexion

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
    // .......
}


Copier après la connexion

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-&gt;em = $em;
    }

    public function saveMeasure(array $measureData): void
    {
        if($measureData['rain_probability'] &lt; 0.40){
            $label = 'LOW';
        }
        elseif ($measureData['rain_probability'] &gt;= 0.40 &amp;&amp; $measureData['rain_probability'] &lt; 0.75){
            $label = 'MEDIUM';
        }
        else{
            $label = 'HIGH';
        }

        $rainMeasure = new RainMeassure();
        $rainMeasure-&gt;setDate($measureData['date']);
        $rainMeasure-&gt;setProbability($measureData['rain_probability']);
        $rainMeasure-&gt;setLabel($label);

        $this-&gt;em-&gt;persist($rainMeasure);
        $this-&gt;em-&gt;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 &lt; 0.40){
            $label = 'LOW';
        }
        elseif ($prob &gt;= 0.40 &amp;&amp; $prob &lt; 0.75){
            $label = 'MEDIUM';
        }
        else{
            $label = 'HIGH';
        }

        return $label;
    }
}


Copier après la connexion

Et maintenant, notre RainMeassureHandler ressemblera à ceci :


class RainMeasureHandler 
{
    private EntityManagerInterface $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this-&gt;em = $em;
    }

    public function saveMeasure(array $measureData): void
    {
        $rainMeasureLabelHandler = new RainMeasureLabelHandler();
        $label = $rainMeasureLabelHandler-&gt;getLabelFromProbability($measureData['rain_probability']);

        $rainMeasure = new RainMeasure();
        $rainMeasure-&gt;setDate($measureData['date']);
        $rainMeasure-&gt;setProbability($measureData['rain_probability']);
        $rainMeasure-&gt;setLabel($label);

        $this-&gt;em-&gt;persist($rainMeasure);
        $this-&gt;em-&gt;flush();
    }
}


Copier après la connexion

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é :

Focusing your tests on the domain. A PHPUnit example

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!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Musée à deux points: toutes les expositions et où les trouver
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Article chaud

Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Musée à deux points: toutes les expositions et où les trouver
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

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

11 meilleurs scripts de raccourcissement d'URL PHP (gratuit et premium) 11 meilleurs scripts de raccourcissement d'URL PHP (gratuit et premium) Mar 03, 2025 am 10:49 AM

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

Travailler avec les données de session Flash dans Laravel Travailler avec les données de session Flash dans Laravel Mar 12, 2025 pm 05:08 PM

Travailler avec les données de session Flash dans Laravel

Misque de réponse HTTP simplifié dans les tests Laravel Misque de réponse HTTP simplifié dans les tests Laravel Mar 12, 2025 pm 05:09 PM

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

Construisez une application React avec un Laravel Back End: Partie 2, React Construisez une application React avec un Laravel Back End: Partie 2, React Mar 04, 2025 am 09:33 AM

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 Curl dans PHP: Comment utiliser l'extension PHP Curl dans les API REST Mar 14, 2025 am 11:42 AM

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

12 meilleurs scripts de chat PHP sur Codecanyon 12 meilleurs scripts de chat PHP sur Codecanyon Mar 13, 2025 pm 12:08 PM

12 meilleurs scripts de chat PHP sur Codecanyon

Introduction à l'API Instagram Introduction à l'API Instagram Mar 02, 2025 am 09:32 AM

Introduction à l'API Instagram

Notifications à Laravel Notifications à Laravel Mar 04, 2025 am 09:22 AM

Notifications à Laravel

See all articles