"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > تركيز اختباراتك على المجال. مثال PHPUnit

تركيز اختباراتك على المجال. مثال PHPUnit

تم النشر بتاريخ 2024-11-03
تصفح:806

مقدمة

يحاول المطورون في كثير من الأحيان اختبار 100% (أو 100%) تقريبًا من التعليمات البرمجية الخاصة بهم. من الواضح أن هذا هو الهدف الذي يجب على كل فريق الوصول إليه في مشاريعه، ولكن من وجهة نظري، يجب اختبار جزء واحد فقط من الكود بالكامل: المجال الخاص بك.

المجال هو، في الأساس، جزء من الكود الخاص بك والذي يحدد ما يفعله المشروع بالفعل. على سبيل المثال، عند الاحتفاظ بكيان في قاعدة البيانات، فإن المجال الخاص بك ليس مسؤولاً عن الاحتفاظ به في قاعدة البيانات، ولكن التأكد من أن البيانات المستمرة منطقية وفقًا لنموذج عملك. من المحتمل، عند حفظ بياناتك في قاعدة البيانات، ستستخدم مكتبة خارجية مثل PHP Doctrine. لقد تم بالفعل اختبار هذه المكتبة بشكل كامل، وليست هناك حاجة لاختبار ما تفعله. إذا قمت بالتمرير إلى العقيدة الصحيحة للبيانات، فسيتم حفظها في قاعدة البيانات دون أي مشاكل.

لا يحاول المثال الموضح في الأقسام التالية إظهار كيفية عمل التصميم المستند إلى المجال، فهناك العديد من المقالات التي تشرح ذلك جيدًا. سأحاول أن أوضح كيف أن تحديد نطاقك بشكل جيد وفصله يمكن أن يساعد في الاختبار بسهولة والتركيز على ما يفعله تطبيقك.

تم بناء المثال على بيئة Symfony واستخدام مكتبة PHPUnit، ولكن الفكرة صالحة لأي لغة أو إطار عمل.

الكود الذي سيتم اختباره

لنتخيل أن تطبيقنا يتصل بواجهة برمجة تطبيقات خارجية تقوم بإرجاع بيانات حول احتمالية هطول الأمطار في تاريخ محدد. تبدو البيانات التي تم إرجاعها كما يلي:


{
   "date" : "2022-12-01",
   "rain_probability" : 0.75
}


الآن، علينا أن نأخذ تلك البيانات ونصنفها باتباع هذا التعيين:

  • احتمالية المطر منخفض
  • احتمالية المطر ≥ 0.40 &&احتمالية المطر متوسطة
  • احتمالية المطر ≥ 0.75: عالية

واحفظ النتيجة في جدول قاعدة بيانات وصفه الكيان التالي:


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


لنقم بإنشاء معالج يحصل على بيانات واجهة برمجة التطبيقات الخارجية، ويضبط التسمية وفقًا لاحتمال المطر ويحفظها في قاعدة البيانات.


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 && $measureData['rain_probability'] setDate($measureData['date']);
        $rainMeasure->setProbability($measureData['rain_probability']);
        $rainMeasure->setLabel($label);

        $this->em->persist($rainMeasure);
        $this->em->flush();
    }
}


إذا حاولنا إنشاء اختبار للمعالج أعلاه، فسنجد أننا سنحتاج إلى إدخال EntityManagerInterface نظرًا لأن السلوك الذي نريد اختباره (وضع علامة وفقًا لقيمة الاحتمال) هو مقترنًا بنفس المعالج الذي يحفظ النتيجة في قاعدة البيانات. يمكننا أن نحاول تحميل EntityManagerInterface باستخدام نماذج وهمية ولكن، هل هذا ضروري؟. من الواضح لا. كما ذكرنا من قبل، يجب أن نحاول التركيز على اختبار السلوك الذي ينتمي إلى مجالنا، وهو الحصول على التسمية الصحيحة وفقًا لاحتمال المطر.

سلوك الفصل الذي نريد اختباره

من أجل تبسيط اختبارنا، سنقوم بنقل السلوك الذي نريد اختباره إلى فئة أخرى:


class RainMeasureLabelHandler 
{
    public function getLabelFromProbability(float $prob): string
    {
        if($prob = 0.40 && $prob 

والآن، سيبدو معالج RainMeassureHandler الخاص بنا بالشكل التالي:


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();
    }
}


الآن يمكننا التركيز على اختبار RainMeasureLabelHandler الذي سيكون جزءًا من مجالنا ولن يكون له أي تبعيات للطبقات الخارجية. سيكون اختباره سهلاً كما هو موضح:

Focusing your tests on the domain. A PHPUnit example

خاتمة

أود أن أقول إن الأنواع الأخرى من الاختبارات ستكون مفيدة أيضًا. ربما لدينا واجهة برمجة تطبيقات ونريد اختبار المدخلات والمخرجات باستخدام بيئة اختبار تتضمن قاعدة بيانات وموارد أخرى قد نحتاجها. ولكن، تذكر أن يتم فصل نطاقك واختباره بالكامل.

بيان الافراج تم إعادة إنتاج هذه المقالة على: https://dev.to/icolomina/focusing-your-tests-on-the-domain-a-phpunit-example-c82?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3