اختبار المكوّنات (اختبار الوحدة)

اختبار المكوّنات (Component Testing)، الذي يسمّيه ISTQB أيضاً اختبار الوحدة (Unit Testing)، هو مستوى الاختبار الذي يفحص أصغر أجزاء البرمجيات القابلة للاختبار المستقل، كلّاً على حدة: دالة، أو صنف (class)، أو وحدة برمجية (module)، أو مكوّن واجهة واحد. والاختبارات هنا شيفرة تستدعي المكوّن مباشرةً بمدخلات مختارة وتقارن ما يعيده بالنتيجة المتوقعة، وتُكتب عادةً بإطار لاختبار الوحدات مثل JUnit أو pytest أو Jest أو Vitest.

مثال ذلك: دالة تطبّق قسيمة خصم بنسبة ⁦10%⁩ على سلة قيمتها ⁦200.00⁩ ريال يجب أن تعيد ⁦180.00⁩. واختبار المكوّن يستدعي الدالة بهذه القيم بالضبط ويتحقق من الإجابة، دون فتح متصفح أو تشغيل التطبيق كاملاً أو الاتصال بخدمة القسائم الحقيقية. ولأن هذه الاختبارات لا تحتاج إلى شيء آخر، يُنفَّذ كل منها عادةً في أجزاء من الثانية، ويستطيع الفريق تشغيلها كلها مع كل تغيير.

لماذا يهم

كثير من العيوب، مثل معادلة خاطئة أو شرط منسيّ أو قيمة فارغة لم تُعالَج، يقع داخل مكوّن واحد. وحين يكشف اختبار المكوّن عيباً منها، يُعرف موضعه فوراً: فالاختبار الفاشل يذكر الدالة والمدخل. أما إذا اكتُشف العيب نفسه لاحقاً عبر واجهة المستخدم، فإنه يحتاج إلى تقرير خطأ وإعادة إنتاج وتحقيق عبر طبقات عدة قبل أن يعرف أحد موضعه.

وبالنسبة إلى المختبِر، فاختبارات المكوّنات هي شبكة الأمان الأولى في استراتيجية الاختبار لدى الفريق. ومعرفة ما تغطيه تتيح لك توجيه اختبارات النظام والقبول إلى ما لا تكشفه إلا تلك المستويات، بدلاً من تكرار فحوص تُشغَّل أصلاً مع كل إيداع (commit). ومعرفة ما لا تستطيع تغطيته، أي السلوك المخفي خلف Stub وMock، تدلّك على مواضع مخاطر التكامل المتبقية.

ما اختبار المكوّن، ومن يكتبه

يصف منهج ISTQB للمستوى التأسيسي ⁦v4.0⁩ اختبار المكوّنات بأنه يركّز على اختبار كل مكوّن معزولاً عن غيره. وكثيراً ما يحتاج إلى دعم خاص، مثل عُدّة الاختبار (Test Harness) أو إطار لاختبار الوحدات، ويُنفّذه المطورون عادةً في بيئة التطوير الخاصة بهم. وفي الممارسة العملية يكون أساس الاختبار (Test Basis) هنا أقرب المواد إلى الشيفرة: التصميم التفصيلي للمكوّن أو مواصفته، والشيفرة نفسها، ونموذج البيانات.

ما يُعدّ مكوّناً يعتمد على الشيفرة. ففي الواجهة الخلفية (back end) يكون عادةً دالة أو صنفاً، وفي الواجهة الأمامية (front end) قد يكون مكوّن واجهة واحداً مثل منتقي التاريخ. كما تستخدم الفرق المصطلحات بطرق مختلفة: فبعضها يقول «اختبار المكوّن» عن شيء أكبر، مثل خدمة كاملة استُبدل كل ما حولها، لذا اسأل عمّا يقصده فريقك قبل أن تقارن الأرقام.

تشترك معظم اختبارات الوحدة في شكل من ثلاثة أجزاء يُسمّى غالباً التجهيز والتنفيذ والتأكيد (Arrange, Act, Assert): جهّز المدخلات والاعتماديات، واستدعِ المكوّن مرة واحدة، وقارن النتيجة بالقيمة المتوقعة. واختبار الوحدة الجيد سريع، ويفحص سلوكاً واحداً، ويعطي النتيجة نفسها على كل جهاز وفي كل تشغيل، واسمه يصرّح بالسلوك المتوقع.

العزل وبدائل الاختبار: Stub وMock وغيرهما

تعتمد المكوّنات الحقيقية على أشياء أخرى: قاعدة بيانات، أو مزوّد دفع، أو التاريخ الحالي، أو خدمة يملكها فريق آخر. ولاختبار مكوّن واحد معزولاً، يستبدل المطور هذه الاعتماديات ببدائل الاختبار (Test Doubles)، وهو مصطلح عام من جيرارد ميزاروس (Gerard Meszaros) مأخوذ من الممثل البديل الذي يؤدي المشاهد الخطرة في الأفلام. والعزل يجعل الاختبار سريعاً وقابلاً للتكرار، ويتيح اختبار مواقف يصعب إحداثها بالاعتمادية الحقيقية، مثل انتهاء المهلة أو قسيمة منتهية الصلاحية.

يستخدم مسرد مصطلحات ISTQB مصطلحين أقدم: الـStub يحلّ محلّ مكوّن يستدعيه المكوّن قيد الاختبار، والمشغّل (Driver) يستدعي المكوّن قيد الاختبار بدلاً من الشيفرة التي تستدعيه في الواقع. والمشغّلات مع بدائل Stub تشكّل معاً عُدّة الاختبار. أما التمييزات الأدق التالية فمصدرها ميزاروس كما شرحها مارتن فاولر (Martin Fowler):

  • Dummy: كائن يُمرَّر لملء قائمة المعاملات فقط، ولا يُستخدم فعلياً.
  • Stub: يقدّم إجابات جاهزة للاستدعاءات التي تحدث أثناء الاختبار، مثل «SAVE10 قسيمة خصمها ⁦10%⁩». ثم يتحقق الاختبار من نتيجة المكوّن (التحقق من الحالة).
  • Spy: بديل من نوع Stub يسجّل أيضاً كيف استُدعي، ليفحص الاختبار الاستدعاءات بعد ذلك.
  • Mock: مُبرمَج مسبقاً بالاستدعاءات التي يتوقعها، ويفشل الاختبار إن لم تحدث، مثل «أرسِل رسالة تأكيد واحدة بالضبط» (التحقق من السلوك).
  • Fake: تنفيذ يعمل فعلاً لكنه مبسّط، مثل قاعدة بيانات في الذاكرة.

جرّبها: مولّد استجابات API وهمية جرّبها: مولّد استجابات خطأ وهمية

مثال تطبيقي: مكوّن القسائم مع خدمة مستبدلة ببديل Stub

المتطلب: «القسيمة الصالحة تخصم نسبتها من المجموع الفرعي للسلة، بما لا يتجاوز الحد الأقصى لخصم القسيمة. والقسيمة غير المعروفة أو المنتهية الصلاحية تترك المجموع الفرعي دون تغيير ويُبلَّغ عنها بأنها غير صالحة». والمكوّن applyCoupon يبحث عن الرمز عبر couponApi، الذي يستدعي في بيئة الإنتاج خدمة قسائم بعيدة. ولا تحتاج إلى معرفة JavaScript لقراءة الشيفرة أدناه: await تنتظر الإجابة، وtest(...) تعرّف اختباراً واحداً له اسم، وexpect(actual).toEqual(expected) تقارن النتيجة الفعلية بالنتيجة المتوقعة.

في الاختبارات، couponApi بديل من نوع Stub يعرف قسيمة واحدة هي SAVE10: خصم ⁦10%⁩ بحد أقصى ⁦50.00⁩ ريالاً. فلم تعد النتائج تعتمد على عمل الخدمة الحقيقية، ولا على القسائم الموجودة في قاعدة بيانات مشتركة، ولا على تاريخ اليوم. ويكتب المطور اختباراً لكل قاعدة، ولكل اختبار قيمة متوقعة محسوبة من المتطلب:

  • ⁦200.00⁩ مع SAVE10 ← المجموع ⁦180.00⁩ (⁦10%⁩ تساوي ⁦20.00⁩، وهي أقل من الحد الأقصى).
  • ⁦1000.00⁩ مع SAVE10 ← المجموع ⁦950.00⁩ (⁦10%⁩ تساوي ⁦100.00⁩، فيُطبَّق الحد الأقصى ⁦50.00⁩).
  • Stub يعيد القسيمة موسومةً بأنها منتهية الصلاحية ← المجموع ⁦200.00⁩، والخطأ COUPON_INVALID.
  • Stub لا يجد شيئاً للرمز FAKE99 ← المجموع ⁦200.00⁩، والخطأ COUPON_INVALID.
  • Stub يرمي الخطأ «service unavailable» ← يتسرّب الخطأ من applyCoupon. والمتطلب لا يقول ماذا يجب أن تفعل عملية إتمام الشراء عندها، فيحمل المختبِر هذا السؤال إلى مالك المنتج. لقد جعل البديل هذا المسار قابلاً للاختبار في ثوانٍ، بينما يصعب إحداثه عمداً بالخدمة الحقيقية.
// Component under test
async function applyCoupon(code, subtotal, couponApi) {
  const coupon = await couponApi.lookup(code);
  if (!coupon || coupon.expired) return { total: subtotal, error: 'COUPON_INVALID' };
  const discount = Math.min((subtotal * coupon.percent) / 100, coupon.maxDiscount);
  return { total: subtotal - discount, error: null };
}

// Arrange: a stub gives a canned answer instead of the remote coupon service
const couponApi = {
  lookup: async (code) =>
    code === 'SAVE10' ? { percent: 10, maxDiscount: 50, expired: false } : null,
};

test('SAVE10 takes 10% off a 200.00 basket', async () => {
  const result = await applyCoupon('SAVE10', 200, couponApi);  // Act
  expect(result).toEqual({ total: 180, error: null });          // Assert
});
اختبار وحدة للمكوّن applyCoupon مع Stub بدل خدمة القسائم: قسيمة جاهزة بخصم ⁦10%⁩ تعطي مجموعاً مفحوصاً قدره ⁦180.00⁩، وStub يرمي خطأً يكشف مسار إخفاق لم يحدّده المتطلب.
  • الـStub يعيد قسيمة معروفة

    • اختبار الوحدة
    • applyCoupon المكوّن قيد الاختبار
    • Stub يؤدي دور couponApi
    1. 1 اختبار الوحدة داخليًا: التجهيز: Stub يعرف القسيمة SAVE10
    2. 2 من اختبار الوحدة إلى applyCoupon: التنفيذ: استدعِ المكوّن مرة واحدة applyCoupon('SAVE10', 200, couponApi)
    3. 3 من applyCoupon إلى Stub يؤدي دور couponApi: يبحث عن الرمز lookup('SAVE10')
    4. 4 من Stub يؤدي دور couponApi إلى applyCoupon: إجابة جاهزة دون أي اتصال بالشبكة ردّ { percent: 10, maxDiscount: 50 }
    5. 5 من applyCoupon إلى اختبار الوحدة: يحسب المجموع ويعيده ردّ ⁦10%⁩ من ⁦200.00⁩ تساوي ⁦20.00⁩، وهي أقل من الحد ⁦50.00⁩ { total: 180, error: null }
    6. 6 اختبار الوحدة داخليًا: التأكيد: يساوي القيمة المتوقعة ⁦180.00⁩ نجاح

    النتيجة: فُحص في أجزاء من الثانية، ولم تُستدعَ خدمة القسائم الحقيقية قط. نجاح

  • الـStub يحاكي تعطّل الخدمة

    • اختبار الوحدة
    • applyCoupon المكوّن قيد الاختبار
    • Stub يؤدي دور couponApi
    1. 1 اختبار الوحدة داخليًا: التجهيز: Stub يرمي خطأً
    2. 2 من اختبار الوحدة إلى applyCoupon: التنفيذ: استدعِ المكوّن مرة واحدة applyCoupon('SAVE10', 200, couponApi)
    3. 3 من applyCoupon إلى Stub يؤدي دور couponApi: يبحث عن الرمز lookup('SAVE10')
    4. 4 من Stub يؤدي دور couponApi إلى applyCoupon: يرمي خطأً ردّ Error('service unavailable')
    5. 5 من applyCoupon إلى اختبار الوحدة: يتسرّب الخطأ: لا مجموع ولا رمز خطأ ردّ
    6. 6 اختبار الوحدة داخليًا: التأكيد: المتطلب لا يحدّد نتيجة متوقعة تنبيه

    النتيجة: سؤال مفتوح لمالك المنتج: ماذا يجب أن تفعل عملية إتمام الشراء حين تتعطّل خدمة القسائم؟ تنبيه

التطوير المقاد بالاختبار: الاختبار أولاً

يذكر منهج ISTQB التطوير المقاد بالاختبار (Test-Driven Development – TDD)، مع التطوير المقاد باختبارات القبول (ATDD) والتطوير المقاد بالسلوك (BDD)، ضمن الأساليب التي تقود فيها الاختباراتُ التطوير. وفي TDD يعمل المطور في دورات قصيرة: يكتب اختبار مكوّن للجزء الصغير التالي من السلوك ويراه يفشل، ثم يكتب من الشيفرة ما يكفي لنجاحه فقط، ثم يحسّن بنية الشيفرة (Refactoring) مع بقاء كل الاختبارات ناجحة. ويسمّي الممارسون هذه الدورة: أحمر، أخضر، إعادة هيكلة.

في مثال القسائم، يكتب المطور أولاً اختبار ⁦180.00⁩ لدالة لم توجد بعد، ثم اختبار الحد الأقصى، ثم اختبار القسيمة المنتهية، ولا يضيف من الشيفرة إلا ما يجعل كل اختبار ينجح. ويترك TDD خلفه حزمة من اختبارات الانحدار السريعة، ويدفع التصميم نحو مكوّنات صغيرة يسهل عزلها. وهو طريقة في التطوير تطبّق مبدأ الاختبار المبكر، لكنه لا يحلّ محلّ مستويات الاختبار الأخرى، لأن اختبارات المطور لا تفحص إلا فهمه هو للمتطلب.

ما يجب أن يعرفه المختبِر ويراجعه

نادراً ما يملك المختبِر اختبارات الوحدة، لكن قراءتها من أرخص المراجعات التي يمكن أن يجريها الفريق. ولا تحتاج إلى أن تكتب الشيفرة بنفسك لتطرح أسئلة جيدة؛ فأسماء الاختبارات ومدخلاتها تخبرك غالباً بما فُحص. انظر في:

  • القواعد: اربط كل معيار من معايير القبول باختبار. والقاعدة التي لا اختبار لها، مثل حدّ أقصى أو قيمة افتراضية، فجوة في هذا المستوى.
  • المدخلات: القيم الفارغة والصفر والحد الدقيق المذكور في المتطلب والصيغ غير الصالحة، لا قيمة معتادة واحدة فقط.
  • التأكيدات: كل اختبار يقارن النتيجة بقيمة محسوبة من المتطلب، لا منسوخة من مخرجات الشيفرة، ولا مجرد «لم يُرمَ أي خطأ».
  • البدائل: بدائل Stub تعيد ما تعيده الاعتمادية الحقيقية فعلاً، بما في ذلك أخطاؤها ونتائجها الفارغة. ويتأكد هذا التطابق لاحقاً في اختبارات التكامل وفي اختبارات العقد (Contract Tests)، أي الاختبارات التي تتحقق من أن الخدمة الحقيقية لا تزال تجيب كما تفترض البدائل.
  • الاستقلال: لا اعتماد على ترتيب التشغيل أو الساعة الحقيقية أو القيم العشوائية أو البيانات المشتركة. والاختبار الذي ينجح ويفشل دون أي تغيير في الشيفرة اختبار متذبذب (flaky).
  • النتائج: اعرف أين تقرير اختبارات الوحدة لكل نسخة بناء (build)؛ فالنسخة التي فشلت اختبارات وحداتها أو تُخطّيت ليست جاهزة لاختبار النظام.

جرّبها: المتطلبات ← حالات اختبار جرّبها: مولّد القيم الحدّية

أخطاء شائعة

  • معاملة اختبارات الوحدة كشأن خاص بالمطورين وعدم قراءتها أبداً، فيختبر الفريق القواعد نفسها مرتين وتفوته القواعد التي لم يختبرها أحد.
  • افتراض أن نجاح اختبارات الوحدة يعني أن الميزة تعمل. فالبدائل تحلّ محلّ الاعتماديات الحقيقية، والافتراضات الخاطئة عن خدمة حقيقية أو قاعدة بيانات أو واجهة برمجية (API) لفريق آخر لا تظهر إلا في مستوى التكامل.
  • تسمية كل اختبار يكتبه المطور اختبارَ وحدة. فالاختبار الذي يتصل بقاعدة بيانات حقيقية أو بالشبكة يُصنَّف عادةً اختبارَ تكامل: أبطأ، وقد يفشل لأسباب خارج المكوّن.
  • بدائل Stub لا تعيد إلا المسار السعيد، أو تعيد حقولاً لا ترسلها الخدمة الحقيقية أبداً؛ فتنجح الاختبارات ويقع الإخفاق في بيئة الإنتاج.
  • الإفراط في استخدام Mock: التحقق من كل استدعاء داخلي، فتنكسر الاختبارات مع كل إعادة هيكلة بينما تكشف عيوباً حقيقية قليلة.
  • نسخ القيم المتوقعة مما أعادته الشيفرة أول مرة بدلاً من حسابها من المتطلب؛ فيصير الاختبار حارساً للعيب.

من منظور ضمان الجودة

أدخِل اختبار المكوّنات في النقاش مبكراً. ففي جلسات تحسين قائمة المهام (refinement)، حين تتضمن القصة قواعد حساب أو قواعد لقبول المدخلات، اقترح أيّها يُفحص في اختبارات الوحدة، وأعطِ المطور شروط الاختبار التي تراها: الحدود، والمدخلات الفارغة وغير الصالحة، واستجابات الخطأ من الاعتماديات. وفي مراجعة الشيفرة أو العمل الثنائي (pairing)، اقرأ أسماء الاختبارات مقابل معايير القبول، واسأل ماذا يعيد كل Stub حين تخفق الاعتمادية التي يحلّ محلّها.

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

تمرين عملي

راجع اختبارات الوحدة لمكوّن رسوم الشحن

المطلوب

كتب مطور المكوّن أدناه وثلاثة اختبارات وحدة له، وكلها ناجحة. راجعها بعين المختبِر: حدّد نوع بديل الاختبار الذي تستخدمه، وتحقق من أجزاء المتطلب R-12 التي تُختبر، واكتشف ما ينقص.

اكتب الاختبارات الناقصة على شكل مدخل وسلوك الـStub والنتيجة المتوقعة. لا تحتاج إلى كتابة شيفرة.

المادة
// المتطلب R-12
// الطلبات بقيمة 300.00 ريال فأكثر توصيلها مجاني. وباقي الطلبات تدفع الرسوم التي
// تعيدها خدمة الأسعار لمدينة التوصيل. وإذا أخفقت خدمة الأسعار، تُحتسب
// الرسوم الافتراضية 25.00 ريالاً.

async function shippingFee(total, city, rateService) {
  if (total > 300) return 0;
  try {
    return await rateService.feeFor(city);
  } catch {
    return 25;
  }
}

// Unit tests: all three pass
const rates = { feeFor: async (city) => 18 };

test('free shipping for large orders', async () => {
  expect(await shippingFee(500, 'Riyadh', rates)).toBe(0);
});

test('small order pays the city fee', async () => {
  expect(await shippingFee(120, 'Riyadh', rates)).toBe(18);
});

test('fee is a number', async () => {
  const fee = await shippingFee(120, 'Jeddah', rates);
  expect(typeof fee).toBe('number');
});
الخطوات
  1. سمِّ بديل الاختبار الذي تستخدمه الاختبارات وحدّد نوعه.
  2. اربط كل جملة في المتطلب R-12 بالاختبار الذي يفحصها.
  3. اسأل عن كل اختبار: هل سيفشل لو كانت الشيفرة خاطئة؟
  4. اكتب الاختبارات الناقصة، وسؤالاً واحداً للمطور أو لمالك المنتج.
إظهار الإجابة النموذجية
الإجابة النموذجية

rates بديل من نوع Stub: يعطي الإجابة الجاهزة نفسها، ⁦18⁩، لكل استدعاء ولا يسجّل شيئاً. والاختبارات تفحص القيمة المُعادة، أي أنها تعتمد التحقق من الحالة (State Verification).

القاعدة الأولى (⁦300.00⁩ فأكثر توصيلها مجاني) لا تُختبر إلا بالقيمة ⁦500⁩ البعيدة عن الحد. والقاعدة الثانية (رسوم المدينة) يفحصها الاختبار الثاني. والقاعدة الثالثة (الرسوم الافتراضية عند إخفاق الخدمة) لا اختبار لها أصلاً.

الاختبارات الناقصة: مجموع ⁦300.00⁩ بالضبط ← رسوم ⁦0⁩. وهذا الاختبار يفشل مع الشيفرة الحالية، لأن total > 300 يفرض رسوماً عند ⁦300.00⁩: عيب يُكتشف قبل أن يفتح أحد التطبيق. وكذلك ⁦299.99⁩ ← ⁦18⁩، وStub ترمي فيه feeFor خطأً ← رسوم ⁦25⁩.

الاختبار الثالث لا يتأكد إلا من أن الرسوم رقم، فسينجح مع أي رسوم خاطئة؛ ضع مكانه تأكيداً لقيمة متوقعة دقيقة. ولأن الـStub يعيد ⁦18⁩ لكل مدينة، فلن يُلاحَظ تمرير مدينة خاطئة: استخدم Stub برسوم مختلفة لكل مدينة (الرياض ⁦18⁩، جدة ⁦22⁩) أو Spy يسجّل المدينة التي تلقّاها.

أسئلة: ما الذي يُعدّ إخفاقاً لخدمة الأسعار: خطأ، أم انتهاء مهلة، أم مدينة غير معروفة؟ هل الرسوم بالريال ورقم مجرّد كما يفترض الـStub؟ وأيّ اختبار تكامل أو اختبار عقد يتحقق من ذلك؟

أسئلة شائعة

هل اختبار المكوّنات هو نفسه اختبار الوحدة؟

في مصطلحات ISTQB نعم: اختبار المكوّنات يُعرف أيضاً باختبار الوحدة. لكن بعض الفرق تستخدم «اختبار المكوّن» لشيء أكبر، مثل مكوّن واجهة يُعرض مع مكوّناته الفرعية، أو خدمة كاملة استُبدلت ببدائل اختبار كلُّ الأشياء من حولها. اسأل عمّا يقصده فريقك.

هل يكتب المختبِرون اختبارات الوحدة؟

عادةً يكتبها المطورون ويصونونها؛ فمنهج ISTQB يصف اختبار المكوّنات بأنه يُنفَّذ عادةً على أيدي المطورين. ويسهم المختبِرون بشروط الاختبار وبمراجعة الاختبارات ونتائجها، وفي بعض الفرق يعملون مع المطورين في ثنائيات أو يكتبون اختبارات بأنفسهم. وأهم ما يضيفونه هو النظرة المستقلة: فالمطور يختبر ما يظن أن الشيفرة يجب أن تفعله.

ما الفرق بين Mock وStub؟

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

إذا كان المطورون يطبّقون TDD، فهل لا يزال الفريق بحاجة إلى مختبِرين؟

نعم. اختبارات TDD تفحص أجزاء صغيرة من الشيفرة مقابل فهم المطور. ولا تفحص كيف تعمل المكوّنات معاً، ولا ما إذا كان النظام كله يلبّي متطلباته، ولا ما إذا كان المتطلب نفسه صحيحاً. هذه الأسئلة من شأن اختبار التكامل واختبار النظام واختبار القبول.

المراجع

  • ISTQB Certified Tester Foundation Level (CTFL) v4.0ISTQB · 2023المنهج التأسيسي لاختبار البرمجيات: مستويات الاختبار وأنواعه وتقنيات تصميم الاختبارات وإدارة الاختبار والأدوات.
  • ISTQB GlossaryISTQBالتعريفات القياسية لمصطلحات الاختبار — حالة الاختبار واختبار الانحدار والخطورة والأولوية وتحليل القيم الحدّية وغيرها.
  • Test Double (Martin Fowler)martinfowler.com · 2006مصطلحات Gerard Meszaros لبدائل الاختبار (Test Doubles) — dummy وfake وstub وspy وmock — كما لخّصها Martin Fowler.
  • Mocks Aren't Stubs (Martin Fowler)martinfowler.com · 2007الفرق بين التحقق من الحالة والتحقق من السلوك، وبين الأسلوب الكلاسيكي وأسلوب الكائنات الوهمية (mockist) في التطوير الموجّه بالاختبار.

تدرّب بأدوات متقن

ولّد استجابات API وهمية كاملة (الحالة والترويسات وجسم JSON) لحالات النجاح والقوائم والتفاصيل والأخطاء والنتائج الفارغة.

المحاكاة

ولّد استجابات خطأ منظّمة (التحقق والمصادقة وعدم العثور وتحديد المعدّل وخطأ الخادم) بالصيغ الشائعة.

المحاكاة

ولّد بيانات JSON وهمية من قالب يحتوي على عناصر نائبة ({{name}} و{{uuid}} و{{int:1-10}} و{{date}} و{{pick:a|b}}).

المحاكاة

حوّل قائمة متطلبات مرقّمة إلى حالات اختبار قابلة للتتبّع مع مصفوفة تربط المتطلبات بالاختبارات.

تصميم الاختبارات

ولّد القيم الحدّية (min-1 وmin وmin+1 والقيمة الاسمية وmax-1 وmax وmax+1) للقيود الرقمية وقيود الطول.

تصميم الاختبارات

للتعمّق أكثر

تقدّمك في هذا الموضوع

جزء من مسار تعلم ضمان الجودة