Test-Driven Development

TDD

التطوير بالاختبار أولاً

Intermediatetesting1 min read
TDDtest-drivenred-green-refactor

Definition

A development practice where you write a failing test first, then write only enough code to make it pass, then refactor — ensuring every line of code is tested.

ممارسة تطوير تكتب فيها اختباراً فاشلاً أولاً ثم تكتب فقط ما يكفي من الكود لتمريره ثم تُعيد الهيكلة — مما يضمن اختبار كل سطر كود.

Why It Matters

TDD forces you to define the expected behavior before you implement it. This prevents 'write code, then write tests that pass because you know what the code does' — which is circular and doesn't prevent bugs.

يُجبرك TDD على تعريف السلوك المتوقع قبل تطبيقه. يمنع هذا 'كتابة الكود ثم كتابة اختبارات تنجح لأنك تعرف ما يفعله الكود' — وهو أمر دائري ولا يمنع الأخطاء.

Full Definition

TDD follows a red-green-refactor cycle: Red — write a test that fails (because the feature doesn't exist yet). Green — write the minimum code needed to make the test pass. Refactor — improve the code while keeping the test green. TDD produces highly testable code by design, because you design the API before you implement it. It tends to produce smaller, more focused functions and better-defined interfaces. TDD is not suitable for all tasks (UI development, exploratory code, AI prompts) but is excellent for business logic, data transformation, and API validation.
يتبع TDD دورة أحمر-أخضر-إعادة هيكلة: أحمر — اكتب اختباراً يفشل (لأن الميزة غير موجودة بعد). أخضر — اكتب الحد الأدنى من الكود اللازم لتمرير الاختبار. إعادة هيكلة — حسّن الكود مع إبقاء الاختبار أخضر. ينتج TDD كوداً قابلاً للاختبار عن طريق التصميم، لأنك تُصمّم API قبل تطبيقه. يميل إلى إنتاج دوال أصغر وأكثر تركيزاً وواجهات أفضل تعريفاً. TDD غير مناسب لجميع المهام (تطوير واجهة المستخدم والكود الاستكشافي وتعليمات الذكاء الاصطناعي) لكنه ممتاز لمنطق الأعمال وتحويل البيانات والتحقق من صحة API.

Example Usage

TDD for `buildSlug('Large Language Model')`: Red: `expect(buildSlug('Large Language Model')).toBe('large-language-model')` — test fails. Green: `function buildSlug(name) { return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, ''); }` — test passes. Refactor: add TypeScript types, export the function.

TDD لـ `buildSlug('Large Language Model')`: أحمر: `expect(buildSlug('Large Language Model')).toBe('large-language-model')` — الاختبار يفشل. أخضر: `function buildSlug(name) { return name.toLowerCase().trim().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, ''); }` — الاختبار ينجح. إعادة هيكلة: إضافة أنواع TypeScript وتصدير الدالة.

Knowledge Graph

Avoid these mistakes when using Test-Driven Development:

1

Writing the implementation first and then tests to match — this produces tests that certify behavior instead of specifying intended behavior

2

Writing too many assertions per test — each test should verify one behavior so failures are easy to diagnose

3

Applying TDD to UI components — UI layout and visual hierarchy are poorly served by TDD; use snapshot testing or visual regression tools instead

Sign in to unlock guided AI explanations from AI Teacher.

Generate a Prompt

Copy this prompt and use it directly with any AI model — no setup needed.

Ready-to-Use Prompt
Help me build a project using Test-Driven Development.

Explain:
1. What is Test-Driven Development and why it matters
2. The core architecture and required tools
3. Step-by-step implementation plan
4. Common mistakes to avoid: Writing the implementation first and then tests to match — this produces tests that certify behavior instead of specifying intended behavior, Writing too many assertions per test — each test should verify one behavior so failures are easy to diagnose, Applying TDD to UI components — UI layout and visual hierarchy are poorly served by TDD; use snapshot testing or visual regression tools instead
5. Best practices and production tips

Official Resources