---
title: "التأكيد الزائد"
type: "test-smell"
slug: "redundant-assertion"
url: "http://localhost:3000/ar/test-smells/redundant-assertion.md"
category: "روائح التحقق"
description: "التأكيد الزائد هو تأكيد يقارن قيمة بنفسها أو بقيمة حرفية مساوية لها بالبناء، فتكون نتيجته محددة مسبقاً ولا يمكنه أن يفشل أو يكتشف انحداراً."
---
# التأكيد الزائد

> التأكيد الزائد هو تأكيد يقارن قيمة بنفسها أو بقيمة حرفية مساوية لها بالبناء، فتكون نتيجته محددة مسبقاً ولا يمكنه أن يفشل أو يكتشف انحداراً.

## Signs and Symptoms

تأكيد **زائد** هو التأكيد الذي تُحدَّد نتيجته قبل أن يعمل الكود قيد الاختبار — المعاملان المتوقع والفعلي _نفس القيمة_، أو كلاهما قيم حرفية معروفة بالتساوي (أو عدم التساوي). يُعرّفه فهرس xUnit/Test Smells (Peruma وآخرون) بأنه «طريقة اختبار تحتوي على عبارة تأكيد تكون فيها المعاملات المتوقعة والفعلية متطابقة»، ويُلاحظ أن التأكيد لذلك «إما صحيح دائماً أو خاطئ دائماً.»

كيف تتعرف عليه:

* `assertEquals`/`toBe`/`toEqual` يتشاركان **نفس التعبير** أو المتغير كحجتين.
* قيمة حرفية منطقية مؤكدة على نفسها، مثل `assertTrue(true)` أو `expect(true).toBe(true)`.
* مقارنة يستطيع المصرِّف/المُدقق إثبات ثباتها، كـ`expect(x === x).toBe(true)`.
* «فحص سلامة» يُعيد صياغة ثابت أعلنته للتو بدلاً من تجربة النظام.

```js
// رائحة: النتيجة ثابتة، الكود قيد الاختبار لا يشارك أبداً
test('user is active', () => {
  expect(true).toBe(true);            // يجتاز دائماً
  const status = 'active';
  expect(status).toBe('active');      // يعيد صياغة القيمة الحرفية، لا يُثبت شيئاً
  expect(user.id).toEqual(user.id);   // قيمة مقارنة بنفسها
});

```

علامة دالة موثوقة: يمكنك حذف كود الإنتاج كلياً والتأكيد يجتاز أخضراً.

## Reasons for the Problem

**لماذا يحدث**

* **تصحيح متبقٍّ.** يُلاحظ الفهرس صراحةً أن هذه الرائحة «يُدخلها المطورون لأغراض التصحيح ثم ينسونها» — عنصر نائب مُرمَّز مثل `assertTrue(true)` يبقى حتى عملية الحفظ.
* **انجراف النسخ-اللصق / إعادة الهيكلة.** تُستبدل متغير في كلا طرفي `assertEquals`، أو تُعاد تسمية قيمة قيد الاختبار فيتطابق الطرف المتوقع والطرف الفعلي على الرمز نفسه.
* **تطابق بالبناء.** تأكيد قيمة مقابل القيمة الحرفية التي عُيِّنت منها للتو، بدلاً من التأكيد مقابل توقع مُشتق باستقلالية.
* **مسرحية التغطية.** يُضاف تأكيد لمجرد تلبية قواعد «كل اختبار يجب أن يؤكد»، دون التحقق من أي شيء ذي معنى.

**لماذا يضر**

* **ثقة زائفة.** الاختبار أخضر دائماً ويُحسب ضمن حجم المجموعة والتغطية، ولكنه لا يتحقق من شيء. لا يستطيع اكتشاف انحدار، فيُخفي ثغرات في شبكة الأمان.
* **الموثوقية بلا معنى.** اختبار لا يمكنه أن يفشل لا يُعطي أي إشارة؛ واختبار خاطئ دائماً عبء ميت يُتجاهل أو يُتخطى بـ`skip`.
* **قابلية القراءة.** يُضيع القراء جهداً في إعادة بناء السلوك المقصود من تأكيد يؤكد حقيقة بديهية؛ لم يعد الاختبار يوثّق متطلباً.
* **قابلية الصيانة.** تتراكم التأكيدات الزائدة كضجيج، وتُضخّم المقاييس، وتتآكل الثقة في المجموعة، مما يشجع الناس على التوقف عن قراءة التأكيدات بعناية.

## Treatment

استبدل الحقيقة البديهية بفحص يربط **قيمة متوقعة معروفة باستقلالية** بـ**النتيجة الفعلية التي ينتجها النظام قيد الاختبار**.

الخطوات:

1. **حدد التأكيد ذا النتيجة الثابتة** — نفس المعامل على كلا الجانبين، أو قيمتان حرفيتان متساويتان.
2. **حدد النية الحقيقية.** ما السلوك الذي كان هذا الاختبار يُقصد التحقق منه؟ إن لم يكن ثمة شيء، فالتأكيد (أو الاختبار بأكمله) ميت ويجب حذفه.
3. **أكّد على مخرجات SUT، لا على المدخلات.** أدخل للنظام مدخلات حقيقية وقارن نتيجته المحسوبة بقيمة متوقعة مُرمَّزة محسوبة يدوياً — لا بإحدى مدخلاته/متغيراته الخاصة.
4. **أبقِ المتوقع/الفعلي متمايزَين.** تأكد أن معامل التوقع ثابت كتبته بقصد وأن المعامل الفعلي هو القيمة المُعادة من الكود قيد الاختبار (يُصلح أيضاً رائحة ترتيب الحجج الخاطئة المرتبطة).
5. **أعِد التشغيل مع كسر التنفيذ** (غيّره) للتأكد من أن التأكيد يمكنه أن يفشل فعلاً.

```js
// قبل — زائد: النتيجة ثابتة
test('discount', () => {
  const total = 100;
  expect(total).toBe(100);          // يعيد صياغة القيمة الحرفية
  expect(applyDiscount).toBe(applyDiscount); // قيمة مقارنة بنفسها
});

// بعد — ذو معنى: مدخل معروف -> نتيجة متوقعة مستقلة
test('applies a 10% discount', () => {
  expect(applyDiscount(100, 0.1)).toBe(90); // نتيجة SUT مقارنةً بقيمة متوقعة محسوبة يدوياً
});

```

إن تُرك عنصر نائب مثل `assertTrue(true)` من التصحيح، احذفه؛ وإن كان بديلاً لفحص حقيقي، اكتب ذلك الفحص.

## Detected by

- **sonar** `javascript:S5863` — يجب ألا تُعطى التأكيدات الحجة ذاتها مرتين (https://rules.sonarsource.com/javascript/RSPEC-5863/)
- **sonar** `java:S5863` — يجب ألا تُعطى التأكيدات الحجة ذاتها مرتين (https://rules.sonarsource.com/java/RSPEC-5863/)
- **eslint** `no-constant-binary-expression` — عدم السماح بتعبيرات لا تؤثر العملية فيها على القيمة (يكتشف المقارنات الذاتية / التأكيدات الدائمة الصحة مثل assert(a === a)) (https://eslint.org/docs/latest/rules/no-constant-binary-expression)
