TDD في Java من الصفر: كيف تغير الاختبارات الكود وتنقذ الأعصاب

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

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

ابدأ الدورة

لماذا TDD ليس عن "كتابة اختبارات"، بل عن "التفكير بطريقة مختلفة"

\n\n

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

\n\n

التطوير القائم على الاختبارات (TDD — Test-Driven Development) هو أسلوب يقلب العملية رأسًا على عقب. أنت لا تكتب الكود ثم الاختبارات. أنت تكتب الاختبار أولاً — وبعدها فقط الكود الذي يجتاز هذا الاختبار. هل يبدو هذا جنونيًا؟ عمليًا، هذا يوفر ساعات وأعصابًا ويجعل الكود أنقى من هواء الجبال في الصباح.

\n\n

في هذه المقالة، سنشرح TDD في Java من خلال أمثلة محددة. لا ماء — فقط كود، دورة Red-Green-Refactor، وسيناريوهات حقيقية. هيا بنا.

\n\n

ما هو TDD وكيف تعمل دورة Red-Green-Refactor

\n\n

يعتمد TDD على ثلاث خطوات بسيطة تتكرر بشكل دوري:

\n\n
    \n
  • Red — نكتب اختبارًا لا يجتاز (يجب أن يفشل).
  • \n
  • Green — نكتب الحد الأدنى من الكود ليجتاز الاختبار.
  • \n
  • Refactor — نحسن الكود دون تغيير سلوكه. تظل الاختبارات خضراء.
  • \n
\n\n

قد يبدو أن هذا يبطئ التطوير. في الواقع — إنه يسرعه. تتوقف عن التخمين "هل هذا يعمل؟". أنت تعلم: إنه يعمل، لأن الاختبار أخضر.

\n\n

المبادئ الرئيسية لـ TDD

\n
    \n
  • لا تكتب سطرًا واحدًا من كود الإنتاج بدون اختبار.
  • \n
  • يجب أن يكون الاختبار بسيطًا قدر الإمكان وأن يختبر سلوكًا واحدًا فقط.
  • \n
  • يُكتب الكود بالقدر الذي يجعله يجتاز الاختبار فقط. لا "دعنا نضيف هذا أيضًا تحسبًا".
  • \n
\n\n

الآن دعنا ننتقل إلى Java و JUnit 5 — الإطار الأكثر شيوعًا لاختبارات الوحدة.

\n\n

إعداد المشروع: Maven, JUnit 5 والهيكل

\n\n

لأمثلتنا، سنستخدم Maven. أضف التبعية إلى pom.xml:

\n\n
<dependency>\n    <groupId>org.junit.jupiter</groupId>\n    <artifactId>junit-jupiter-api</artifactId>\n    <version>5.10.0</version>\n    <scope>test</scope>\n</dependency>
\n\n

هيكل المجلدات قياسي لـ Maven:

\n
src/\n  main/java/com/example/\n  test/java/com/example/
\n\n

نضع جميع فئات الاختبار في src/test/java. عادةً ما يتطابق اسم فئة الاختبار مع اسم الفئة المختبرة + اللاحقة Test. على سبيل المثال، Calculator → CalculatorTest.

\n\n

دورة TDD الأولى: كتابة آلة حاسبة من الصفر

\n\n

المهمة: إنشاء دالة add(int a, int b) تُرجع المجموع. وفقًا لـ TDD، نبدأ ليس بالفئة، بل بالاختبار.

\n\n

الخطوة 1: Red — نكتب اختبارًا سيفشل

\n\n
import org.junit.jupiter.api.Test;\nimport static org.junit.jupiter.api.Assertions.*;\n\npublic class CalculatorTest {\n\n    @Test\n    void shouldAddTwoNumbers() {\n        Calculator calc = new Calculator();\n        int result = calc.add(2, 3);\n        assertEquals(5, result);\n    }\n}
\n\n

نحاول التشغيل — المترجم يشتكي: الفئة Calculator غير موجودة. ممتاز، الضوء الأحمر مضاء.

\n\n

الخطوة 2: Green — نكتب الحد الأدنى من الكود

\n\n

ننشئ فئة Calculator بدالة تُرجع المجموع ببساطة:

\n\n
public class Calculator {\n    public int add(int a, int b) {\n        return a + b;\n    }\n}
\n\n

نشغل الاختبار — أخضر. التطبيق الأدنى الممكن نجح.

\n\n

الخطوة 3: Refactor

\n\n

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

\n\n

أكثر تعقيدًا

المدونات

توصيات الكتب