TDD في PHP: تطوير البرمجيات باختبارات احترافية

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا يستحق كودك الاحترام (والاختبارات)

\n\n

تخيل: تكتب كودًا يعمل بشكل مثالي، كل شيء على ما يرام. لكن بعد شهر، تعود إلى المشروع لإضافة ميزة جديدة — وفجأة ينهار كل شيء. هل يبدو هذا مألوفًا؟ إذا كان الأمر كذلك، فإن TDD في PHP هو ما تحتاجه تمامًا. التطوير الموجه بالاختبارات (Test-Driven Development) ليس مجرد موضة عابرة، بل فلسفة تغير نظرتك للكود. في هذا المقال، سنشرح كيف يحول TDD الفوضى إلى نظام، والأخطاء إلى آثار من الماضي. ستتعلم كيفية كتابة اختبارات PHP التي توفر وقتك فعليًا، مع أمثلة عملية. هيا بنا!

\n\n

ما هو TDD ولماذا تحتاجه في PHP؟

\n\n

TDD في PHP هو منهجية تبدأ بكتابة الاختبار أولاً، ثم كتابة الكود الذي يجتاز هذا الاختبار. يبدو غريبًا؟ في الحقيقة، إنه عبقري. بدلاً من التخمين حول ما إذا كان كودك يعمل، تحصل على تغذية راجعة فورية. المبادئ الأساسية لـ TDD:

\n\n
    \n
  • أحمر — اكتب اختبارًا يفشل (لأن الكود لم يُكتب بعد).
  • \n
  • أخضر — اكتب الحد الأدنى من الكود ليجتاز الاختبار.
  • \n
  • إعادة هيكلة — حسّن الكود دون كسر الاختبارات.
  • \n
\n\n

تتكرر هذه الدورة مرارًا وتكرارًا. في PHP، يعتبر TDD مفيدًا بشكل خاص لأن اللغة تُستخدم غالبًا في تطبيقات الويب، حيث يمكن أن تكون الأخطاء مكلفة. تساعد اختبارات PHPUnit (الإطار الرئيسي للاختبار) في تجنب الانتكاسات وتجعل الكود شفافًا. بالإضافة إلى ذلك، ينظم TDD عملك: تبدأ بالتفكير في التصميم قبل كتابة الكود.

\n\n

إعداد بيئة اختبار PHP

\n\n

قبل الغوص في الأمثلة، دعنا نجهز البيئة. لـ التطوير بالاختبارات في PHP، نحتاج إلى PHPUnit. التثبيت بسيط:

\n\n
composer require --dev phpunit/phpunit ^10
\n\n

أنشئ مجلد tests في جذر المشروع. بداخله، أنشئ ملف CalculatorTest.php. تأكد من تثبيت PHP 8.0+. الآن كل شيء جاهز لأول اختبار.

\n\n

الاختبار الأول: بناء آلة حاسبة باستخدام TDD

\n\n

لنقم بإنشاء آلة حاسبة بسيطة. أولاً — الاختبار. هذا مثال كلاسيكي لـ TDD في PHP للمبتدئين.

\n\n

الخطوة 1: أحمر (كتابة اختبار فاشل)

\n\n

أنشئ tests/CalculatorTest.php:

\n\n
<?php\n\nuse PHPUnit\\Framework\\TestCase;\n\nclass CalculatorTest extends TestCase\n{\n    public function testAddition()\n    {\n        $calculator = new Calculator();\n        $result = $calculator->add(2, 3);\n        $this->assertEquals(5, $result);\n    }\n}
\n\n

شغّل الاختبار:

\n\n
./vendor/bin/phpunit tests/CalculatorTest.php
\n\n

نتوقع خطأ: Class "Calculator" not found. كل شيء حسب الخطة — هذه هي المرحلة الحمراء.

\n\n

الخطوة 2: أخضر (كتابة الحد الأدنى من الكود)

\n\n

أنشئ src/Calculator.php:

\n\n
<?php\n\nclass Calculator\n{\n    public function add(int $a, int $b): int\n    {\n        return $a + $b;\n    }\n}
\n\n

لا تنس تضمين التحميل التلقائي في الاختبار:

\n\n
require_once __DIR__ . '/../src/Calculator.php';
\n\n

شغّل الاختبار مرة أخرى — أخضر! الآن مرحلة إعادة الهيكلة. في هذه المرحلة، الكود بسيط، لكن لاحقًا يمكنك تحسينه دون خوف من كسره.

\n\n

الخطوة 3: إعادة الهيكلة بثقة

\n\n

لنفترض أننا نريد إضافة التحقق من الأنواع. نغير الكود:

\n\n
public function add(int $a, int $b): int\n{\n    if (!is_int($a) || !is_int($b)) {\n        throw new InvalidArgumentException('Only integers allowed');\n    }\n    return $a + $b;\n}
\n\n

شغّل الاختبارات — ما زالت ناجحة. يمنحك TDD الشجاعة للتجربة.

\n\n

TDD المتقدم: التعامل مع الاستثناءات والـ Mocks

\n\n

عندما تتقن الأساسيات، انتقل إلى السيناريوهات المعقدة. على سبيل المثال، اختبار الاستثناءات. في اختبارات الوحدة PHP، هذا

المدونات

توصيات الكتب