تمرين عملي: اختبار دالة getCoupons

الكاتب: قالب اقرأتاريخ النشر: آخر تحديث: وقت القراءة:
للقراءة
عدد الكلمات:
كلمة
عدد التعليقات: 0 تعليق
نبذة عن المقال: تمرين عملي على اختبار دالة JavaScript باستخدام Vitest. تعلم كيفية استخدام matchers متنوعة لكتابة تأكيدات (assertions) دقيقة وفعالة للمصفوفات والكائنات

مرحبًا بك في تمرين جديد! بعد أن تعلمنا عن أهمية كتابة تأكيدات (Assertions) جيدة وكيفية استخدام الـ Matchers بفعالية، حان الوقت لتطبيق هذه المهارات عمليًا. في هذا التمرين، سنقوم بكتابة مجموعة من الاختبارات لدالة بسيطة تُرجع قائمة بكوبونات الخصم. هذا سيساعدنا على ترسيخ فهمنا لكيفية اختبار المصفوفات والكائنات.

تمرين عملي: اختبار دالة getCoupons

الهدف من التمرين

الهدف هو التأكد من أنك تستطيع:

  1. اختيار الـ Matcher المناسب لكل حالة اختبار.
  2. اختبار بنية البيانات المُرجعة (Array of Objects).
  3. التحقق من القيم والخصائص داخل الكائنات الموجودة في المصفوفة.
  4. كتابة اختبارات شاملة تغطي جوانب متعددة من الدالة.

وصف الدالة getCoupons

الدالة التي سنختبرها بسيطة جدًا. كل ما تفعله هو إرجاع مصفوفة ثابتة (hard-coded) من كائنات الكوبونات. كل كائن يمثل كوبونًا ويحتوي على خاصيتين:

  • code: سلسلة نصية (string) تمثل رمز الكوبون.
  • discount: رقم (number) يمثل نسبة الخصم (على سبيل المثال، 0.1 لخصم 10%).

ملفات البداية

للبدء، سنحتاج إلى ملفين: ملف الدالة نفسها، وملف الاختبار الخاص بها.

1. ملف الدالة (coupons.js)

قم بإنشاء ملف باسم coupons.js وأضف الكود التالي بداخله. هذه هي الدالة التي سنكتب لها الاختبارات.

JavaScript
// src/coupons.js

export const getCoupons = () => {
  return [
    { code: 'SAVE10', discount: 0.1 },
    { code: 'SALE20', discount: 0.2 },
    { code: 'NEWUSER', discount: 0.15 },
  ];
};

2. ملف الاختبار (coupons.test.js)

الآن، قم بإنشاء ملف الاختبار coupons.test.js بجانب الملف السابق. هذا هو المكان الذي ستكتب فيه اختباراتك.

JavaScript
// tests/coupons.test.js

import { getCoupons } from '../src/coupons';

describe('getCoupons', () => {
  // Your tests will go here
});

المتطلبات (Requirements)

مهمتك هي كتابة مجموعة من الاختبارات داخل كتلة describe للتحقق من السلوك الصحيح لدالة getCoupons. عليك كتابة الاختبارات التالية:

  1. الاختبار الأول: يجب أن تتحقق من أن الدالة تُرجع مصفوفة (array).
  2. الاختبار الثاني: يجب أن تتحقق من أن المصفوفة المُرجعة ليست فارغة وأنها تحتوي على 3 كوبونات بالضبط.
  3. الاختبار الثالث: يجب أن تتحقق من أن المصفوفة تحتوي على كوبون خصم محدد. على سبيل المثال، تأكد من وجود الكوبون { code: 'SALE20', discount: 0.2 }.
  4. تلميح

    تذكر الفرق بين toContain و toContainEqual عند التعامل مع الكائنات.

  5. الاختبار الرابع: يجب أن تتحقق من أن كل كوبون في المصفوفة له بنية صحيحة، أي أنه كائن يحتوي على خاصيتي code (من نوع string) و discount (من نوع number).
  6. الاختبار الخامس: يجب أن تتحقق من أن قيمة الخصم discount لكل كوبون هي قيمة موجبة.

خذ وقتك في محاولة حل التمرين بنفسك قبل النظر إلى الحل المقترح. هذه هي أفضل طريقة للتعلم.


الحل المقترح

هل أنت مستعد لمقارنة حلك؟ إليك الحل الكامل مع شرح لكل اختبار.

JavaScript
// tests/coupons.test.js

import { getCoupons } from '../src/coupons';

describe('getCoupons', () => {
  it('should return an array of coupons', () => {
    const coupons = getCoupons();
    // Test 1: Check if the result is an array.
    // Using `toBeInstanceOf` is a robust way to check for type.
    expect(coupons).toBeInstanceOf(Array);
  });

  it('should return an array with 3 coupons', () => {
    const coupons = getCoupons();
    // Test 2: Check for a specific array length.
    // `toHaveLength` is the most idiomatic way to check the size of an array.
    expect(coupons).toHaveLength(3);
  });

  it('should include a specific coupon', () => {
    const coupons = getCoupons();
    // Test 3: Check for the presence of a specific object.
    // `toContainEqual` is used because it checks for deep equality (object values),
    // whereas `toContain` checks for referential equality (same object instance).
    expect(coupons).toContainEqual({ code: 'SALE20', discount: 0.2 });
  });

  it('should ensure every coupon has the correct structure and types', () => {
    const coupons = getCoupons();
    // Test 4: Verify the structure and types of each object in the array.
    // We loop through each coupon and make assertions on its properties.
    coupons.forEach(coupon => {
      expect(coupon).toHaveProperty('code');
      expect(typeof coupon.code).toBe('string');

      expect(coupon).toHaveProperty('discount');
      expect(typeof coupon.discount).toBe('number');
    });
  });

  it('should ensure all discount values are positive', () => {
    const coupons = getCoupons();
    // Test 5: Verify a specific constraint on a property value.
    // This ensures our data adheres to business logic (discounts can't be negative).
    coupons.forEach(coupon => {
      expect(coupon.discount).toBeGreaterThan(0);
    });
  });
});

تحليل الحل

  • الاختبار الأول: استخدمنا toBeInstanceOf(Array) للتحقق من أن الناتج هو مصفوفة. هذه طريقة موثوقة للتحقق من النوع.
  • الاختبار الثاني: استخدمنا toHaveLength(3) وهو الـ Matcher المخصص للتحقق من طول المصفوفات أو السلاسل النصية. إنه أكثر وضوحًا من expect(coupons.length).toBe(3).
  • الاختبار الثالث: هنا يكمن الفارق الدقيق. عند التحقق من وجود كائن في مصفوفة، نستخدم toContainEqual. لو استخدمنا toContain لفشل الاختبار، لأن toContain يتحقق مما إذا كان نفس الكائن موجودًا في الذاكرة، بينما toContainEqual يتحقق من وجود كائن له نفس القيم (deep equality).
  • الاختبار الرابع والخامس: قمنا بالمرور على كل عنصر في المصفوفة باستخدام forEach للتحقق من البنية والقيم الداخلية لكل كائن. هذا يضمن لنا أن جميع البيانات في المصفوفة متسقة وصحيحة. لقد تحققنا من وجود الخصائص (toHaveProperty)، ونوعها (typeof), وقيمتها (toBeGreaterThan).

خلاصة

لقد قمت للتو بكتابة مجموعة اختبارات شاملة لدالة بسيطة. هذا التمرين يوضح كيف أن اختبار دالة واحدة قد يتطلب عدة حالات اختبار (test cases) للتأكد من كل جانب من جوانب سلوكها، بدءًا من نوع القيمة المُرجعة، مرورًا بحجمها ومحتواها، وانتهاءً ببنية وقيم العناصر داخلها. لقد تدربت على استخدام toBeInstanceOf, toHaveLength, toContainEqual, ودمج الحلقات مع التأكيدات للتحقق من كل عنصر في مصفوفة.

قد تُعجبك هذه المشاركات

إرسال تعليق

ليست هناك تعليقات

7627059358572141466

العلامات المرجعية

قائمة العلامات المرجعية فارغة ... قم بإضافة مقالاتك الآن

    البحث