---
title: "الاختبار الفارغ"
type: "test-smell"
slug: "empty-test"
url: "http://localhost:3000/ar/test-smells/empty-test.md"
category: "روائح العناصر غير الضرورية"
description: "الاختبار الفارغ هو طريقة اختبار تحتوي على جسم خالٍ من أي عبارات قابلة للتنفيذ، وبالتالي ينجح دائماً دون التحقق من أي شيء."
---
# الاختبار الفارغ

> الاختبار الفارغ هو طريقة اختبار تحتوي على جسم خالٍ من أي عبارات قابلة للتنفيذ، وبالتالي ينجح دائماً دون التحقق من أي شيء.

## Signs and Symptoms

يوجد اختبار ويتم الإبلاغ عنه على أنه **ناجح**، ولكن جسمه لا يحتوي على كود قابل للتنفيذ — لا تهيئة، ولا تشغيل، ولا تحقق. الأشكال الدالة:

```js
// جسم فارغ تماماً
test('calculates tax', () => {});

// تعليق TODO / تعليق عنصر نائب فقط
it('should reject invalid input', () => {
  // TODO: اكتب هذا بمجرد استقرار واجهة برمجة التطبيقات (API)
});

// تم تحويل كل شيء إلى تعليق
it('parses the auth header', () => {
  // const result = parse(header);
  // expect(result).toEqual(expected);
});

```

كيف تكتشفه:

* يعد اسم الاختبار بسلوك معين، ولكن جسم الاختبار يحتوي على `{}` أو مسافات فارغة أو تعليقات فقط.
* يظهر ملخص بيئة التشغيل الاختبار كـ **ناجح** (أخضر)، وليس كمتخطى/معلق — وهذا هو ما يجعله خطيراً.
* تكون تغطية الكود للميزة المسماة صفراً بشكل مريب على الرغم من وجود "اختبار لها".
* أثناء المراجعة، يضيف الفارق (diff) حالة اختبار ولكن بدون استدعاء `expect`/`assert` call.

مرتبط ولكنه متميز: الاختبار الذي يحتوي على تهيئة ويستدعي النظام تحت الاختبار ولكنه لا يجري **أي تحقق** يمثل رائحة _الاختبار الخالي من التحقق / الاختبار المجهول_. بينما الاختبار الفارغ هو الحالة الأكثر تطرفاً حيث يكون جسم الاختبار خالياً تماماً من أي عبارات.

## Reasons for the Problem

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

* تم إنشاء هيكل الاختبار كعنصر نائب (مثل أسلوب TDD "اكتب الاسم أولاً") ولم يتم ملؤه أبداً.
* تم تحويل الكود إلى تعليق لتصحيح خطأ أو لإسكات اختبار غير مستقر، ثم تم رفعه ونسيانه.
* أنتج مولد الأكواد أو محرّر الأكواد (IDE) اختباراً هيكلياً فارغاً لم يكمله أحد.
* أراد المطور "حجز" اسم اختبار لوقت لاحق ولكنه استخدم جسماً فارغاً بدلاً من علامة todo صريحة.

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

* **الثقة الزائفة (الجزء الأسوأ).** تبلغ معظم بيئات تشغيل الاختبارات عن نجاح الاختبار الفارغ كـ _ناجح_، وليس كمتخطى. ستظهر جميع بيئات التشغيل مثل JUnit وJest وVitest وغيرها لوناً أخضر لـ `test('x', () => {})`. تبدو مجموعة الاختبارات وكأنها تغطي السلوك، ولكن لن يتم التقاط أي تراجع في كود الإنتاج أبداً — وهو أمر ربما يكون أسوأ من عدم وجود اختبار على الإطلاق، لأن علامة النجاح الخضراء تضلل بشكل نشط.
* **سهولة القراءة.** يرى القارئ اختباراً باسم `should reject invalid input` ويفترض منطقياً أن هذا السلوك قد تم التحقق منه. يوثق الاسم نية لا يقدمها جسم الاختبار أبداً.
* **سهولة الصيانة.** تضخم الاختبارات الفارغة عدد الاختبارات وتصور التغطية بالاسم، مما يخفي الفجوات الحقيقية ويجعل من الصعب التمييز بين العناصر النائبة المقصودة وتلك المهجورة.
* **يضعف الثقة.** بمجرد أن يدرك المساهمون في الكود أن "النجاح" لا يعني "التحقق من الصحة"، تضعف مصداقية مجموعة الاختبارات بأكملها.

## Treatment

قرر ما إذا كان يجب أن يكون الاختبار _موجوداً بالفعل_، ثم اجعل بيئة التشغيل تظهر الحقيقة.

**1\. إذا كان يجب اختبار السلوك الآن — املأ جسم الاختبار.** أضف خطوات الترتيب والتنفيذ والتحقق (arrange/act/assert) بحيث يختبر الكود فعلياً:

```js
// قبل — ناجح (أخضر)، ولكنه لا يتحقق من شيء
test('rounds half up', () => {});

// بعد — توقع حقيقي
test('rounds half up', () => {
  expect(round(2.5)).toBe(3);
});

```

**2\. إذا كان عنصراً نائباً حقيقياً — ضع عليه علامة معلق صريحة** بحيث تبلغ بيئة التشغيل عنه كـ todo/skipped (مرئي، وليس أخضر كاذباً) بدلاً من ترك جسمه فارغاً:

```js
// قبل
it('should reject invalid input', () => {
  // TODO
});

// بعد — يظهر كـ todo في التقرير، ولا يظهر أبداً كـ "ناجح"
it.todo('should reject invalid input');   // Jest / Vitest
// أو test.skip(...) / xit(...) مع تذكرة تتبع

```

**3\. إذا كان الاختبار قديماً وغير مستخدم — فاحذفه.** الاختبار المحذوف يعبر عن الحقيقة؛ بينما الاختبار الفارغ كذبة تكلف صيانة.

**4\. استعد المنطق المعلق.** إذا كان جسم الاختبار معلقاً بالكامل، فإما أن تلغي التعليق وتصلحه أو تزيل الاختبار؛ ولا تشحن أبداً كود اختبار معلقاً كـ "تنفيذ".

**5\. أضف حماية.** فعّل قاعدة فحص وجود التحقق (assertion-presence lint rule) (انظر كواشف الرائحة) في التكامل المستمر (CI) بحيث تفشل الاختبارات الفارغة/الخالية من التحقق في البناء بدلاً من النجاح بصمت.

## Detected by

- **eslint-jest** `expect-expect` — eslint-plugin-jest: expect-expect (يحدد الاختبارات التي لا تحتوي على تحقق، بما في ذلك الأجسام الفارغة) (https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/expect-expect.md)
- **eslint-vitest** `expect-expect` — eslint-plugin-vitest: expect-expect (يفرض وجود توقع واحد على الأقل لكل اختبار) (https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/expect-expect.md)
- **eslint** `no-empty-function` — ESLint core: no-empty-function (قاعدة عامة؛ تحدد جسم الدالة السهمية/الدالة الفارغة في استدعاء اختبار فارغ) (https://eslint.org/docs/latest/rules/no-empty-function)
- **sonar** `S2699` — SonarSource: S2699 "يجب أن تحتوي الاختبارات على تحققات" (حظر؛ يحدد الاختبارات الخالية من التحقق والاختبارات الفارغة؛ وتوجد مكافئات لـ Java/C#/Python) (https://rules.sonarsource.com/javascript/RSPEC-2699/)
- **pmd** `JUnitTestsShouldIncludeAssert` — PMD (Java): JUnitTestsShouldIncludeAssert (يحدد اختبارات JUnit التي تفتقر إلى تحقق، بما في ذلك الاختبارات الفارغة) (https://pmd.github.io/pmd/pmd_rules_java_bestpractices.html#junittestsshouldincludeassert)
