تعرّف على موجه توليد اختبارات لـ Claude Code ينتج اختبارات ذات دلالة قوية عن طريق استهداف الحدود، الثوابت، وأنماط الفشل بدلاً من مسارات النجاح.

غالبًا ما تبدو مجموعات الاختبارات المولدة آليًا مثيرة: عشرات الاختبارات، الكثير من إعداد البيانات، وكل اسم دالة يظهر مكانًا ما. لكن العديد من هذه الاختبارات هي مجرد فحوص "يعمل عندما يكون كل شيء طبيعيًا". تمر بسهولة، ونادرًا ما تكتشف أخطاء، ومع ذلك تكلف وقتًا لقراءتها وصيانتها.
مع موجه توليد الاختبارات النموذجي لـ Claude Code، يميل النموذج إلى عكس أمثلة الدخل التي يراها. تحصل على تباينات تبدو مختلفة لكنها تغطي نفس السلوك. النتيجة هي مجموعة كبيرة بتغطية رفيعة حيث يكون الأمر مهمًا.
الاختبارات ذات الدلالة العالية مختلفة. إنها المجموعة الصغيرة التي كانت ستكتشف حادث الشهر الماضي. تفشل عندما يتغير السلوك بطريقة خطرة، وتظل ثابتة عند عمليات إعادة تشكيل غير ضارة. اختبار واحد ذو دلالة عالية يمكن أن يساوي عشرين فحصًا من نوع "يعيد القيمة المتوقعة".
التوليد منخفض القيمة لمسارات النجاح عادةً ما تظهر عليه بعض الأعراض الواضحة:
تخيل دالة تطبق رمز خصم. اختبارات مسار النجاح تؤكد أن "SAVE10" يخفض السعر. الأخطاء الحقيقية تختبئ في أماكن أخرى: أسعار صفرية أو سلبية، رموز منتهية الصلاحية، حواف التقريب، أو حدود الحد الأقصى للخصم. هذه هي الحالات التي تسبب جداول إجمالي خاطئة، عملاء غاضبون، واسترجاعات في منتصف الليل.
الهدف هو الانتقال من "مزيد من الاختبارات" إلى "اختبارات أفضل" عن طريق استهداف ثلاثة أشياء: الحدود، أنماط الفشل، والثوابت.
إذا أردت اختبارات وحدة ذات دلالة عالية، توقف عن طلب "المزيد من الاختبارات" وابدأ بطلب ثلاثة أنواع محددة. هذا جوهر موجه توليد الاختبارات لـ Claude Code الذي ينتج تغطية مفيدة بدلًا من كومة فحوص "تعمل على مدخلات طبيعية".
الحدود هي حواف ما يقبله أو ينتجه الكود. العديد من العيوب الحقيقية هي أخطاء فرق واحد، حالات الحالة الفارغة، أو مشاكل المهلة التي لا تظهر في مسار النجاح.
فكر من حيث الحدود الدنيا والقصوى (0، 1، الحد الأقصى للطول)، فارغ مقابل موجود ("", [], nil)، فرق واحد (n-1، n، n+1)، وحدود زمنية (قرب نقطة القطع).
مثال: إذا كان واجهة برمجة التطبيقات تقبل "حتى 100 عنصر"، اختبر 100 و101، وليس فقط 3.
أنماط الفشل هي الطرق التي يمكن أن ينكسر بها النظام: مدخلات سيئة، تبعيات مفقودة، نتائج جزئية، أو أخطاء متداخلة. اختبارات أنماط الفشل الجيدة تتحقق من السلوك تحت الضغط، وليس فقط المخرجات في الظروف المثالية.
مثال: عندما يفشل استدعاء قاعدة البيانات، هل تعيد الدالة خطأ واضحًا وتتجنب كتابة بيانات جزئية؟
الثوابت هي حقائق يجب أن تبقى صحيحة قبل وبعد الاستدعاء. تحول الصحة الغامضة إلى تأكيدات صارمة.
أمثلة:
عند التركيز على هذه الأهداف الثلاثة، تحصل على اختبارات أقل، لكن كل اختبار يحمل دلالة أكبر.
إذا طلبت اختبارات مبكرًا جدًا، فعادةً ما تحصل على كومة من فحوص "تعمل كما هو متوقع". إصلاح بسيط هو كتابة عقد صغير أولًا، ثم توليد الاختبارات من ذلك العقد. إنها أسرع طريقة لتحويل موجه توليد الاختبارات إلى شيء يجد أخطاء حقيقية.
العقدة المفيدة قصيرة بدرجة يمكن قراءتها بِنَفَس واحد. استهدف 5 إلى 10 أسطر تجيب عن ثلاثة أسئلة: ما الذي يدخل، ما الذي يخرج، وما الذي يتغير أيضًا.
اكتب العقد بلغة بسيطة، وليس كودًا، وضمن فقط ما يمكنك اختباره.
بمجرد حصولك على ذلك، امسحه بحثًا عن أين يمكن أن تكسر الواقع افتراضاتك. تلك تصبح حالات الحدود (min/max، صفر، تجاوز السعة، سلاسل فارغة، مكررات) وأنماط الفشل (مهل زمنية، رفض إذن، انتهاكات قيد فريد، مدخلات تالفة).
إليك مثال ملموس لميزة مثل reserveInventory(itemId, qty):
قد تقول العقدة إن qty يجب أن يكون عددًا صحيحًا موجبًا، يجب أن تكون الدالة ذرية، ويجب ألا تُنشئ مخزونًا سالبًا. هذا يقترح فورًا اختبارات ذات دلالة عالية: qty = 0، qty = 1، qty أكبر من المتوفر، استدعاءات متزامنة، وخطأ قاعدة بيانات مجبر في منتصف العملية.
إذا كنت تستخدم أداة إنشاء أكواد تفاعلية مثل Koder.ai، ينطبق نفس سير العمل: اكتب العقد في الدردشة أولًا، ثم ولّد اختبارات تهاجم الحدود وأنماط الفشل وقائمة "يجب ألا يحدث" مباشرة.
استخدم هذا موجه توليد الاختبارات لـ Claude Code عندما تريد اختبارات أقل لكن كل منها ذو وزن. التحرك الأساسي هو إجبار خطة اختبار أولًا، ثم توليد كود الاختبار فقط بعد موافقتك على الخطة.
You are helping me write HIGH-SIGNAL unit tests.
Context
- Language/framework: <fill in>
- Function/module under test: <name + short description>
- Inputs: <types, ranges, constraints>
- Outputs: <types + meaning>
- Side effects/external calls: <db, network, clock, randomness>
Contract (keep it small)
1) Preconditions: <what must be true>
2) Postconditions: <what must be true after>
3) Error behavior: <how failures are surfaced>
Task
PHASE 1 (plan only, no code):
A) Propose 6-10 tests max. Do not include “happy path” unless it protects an invariant.
B) For each test, state: intent, setup, input, expected result, and WHY it is high-signal.
C) Invariants: list 3-5 invariants and how each will be asserted.
D) Boundary matrix: propose a small matrix of boundary values (min/max/empty/null/off-by-one/too-long/invalid enum).
E) Failure modes: list negative tests that prove safe behavior (no crash, no partial write, clear error).
Stop after PHASE 1 and ask for approval.
PHASE 2 (after approval):
Generate the actual test code with clear names and minimal mocks.
خدعة عملية هي طلب مصفوفة الحدود كجدول مضغوط، حتى تكون الفجوات واضحة:
| Dimension | Valid edge | Just outside | “Weird” value | Expected behavior |
|---|---|---|---|---|
| length | 0 | -1 | 10,000 | error vs clamp vs accept |
إذا اقترح Claude عشرين اختبارًا، اضغط للخلف. اطلب منه دمج الحالات المماثلة والاحتفاظ فقط بما سيكتشف خطأ حقيقي (فرق واحد، نوع خطأ خاطئ، فقدان بيانات صامت، ثابت مكسور).
ابدأ بعقد صغير وملموس للسلوك الذي تريده. ألصق توقيع الدالة، وصفًا قصيرًا للمدخلات والمخرجات، وأي اختبارات قائمة (حتى لو كانت مسارات نجاح فقط). هذا يبقي النموذج مرتبطًا بما يفعله الكود فعليًا، وليس بما يخمنه.
بعد ذلك، اطلب جدول مخاطر قبل طلب أي كود اختبار. اطلب ثلاثة أعمدة: حالات الحدود (حواف الصلاحية)، أنماط الفشل (مدخلات سيئة، بيانات مفقودة، مهلات)، والثوابت (أشياء يجب أن تبقى صحيحة). أضف جملة واحدة لكل صف: "لماذا يمكن أن ينكسر هذا". يكشف جدول بسيط الفجوات أسرع من كومة ملفات اختبار.
ثم اختر أصغر مجموعة اختبارات يكون لكل منها غرض فريد في كشف الأخطاء. إذا فشل اختباران لنفس السبب، احتفظ بالأقوى.
قاعدة اختيار عملية:
أخيرًا، اطلب شرحًا قصيرًا لكل اختبار: أي خطأ سيكشفه إذا فشل. إذا كان الشرح غامضًا ("يتحقق من السلوك"), فربما الاختبار ذو إشارة منخفضة.
الثابت هو قاعدة يجب أن تبقى صحيحة بغض النظر عن أي مدخل صالح تمرره. مع الاختبار القائم على الثوابت، تكتب القاعدة أولًا بلغة بسيطة، ثم تحولها إلى تأكيد يمكن أن يفشل بصوت عالٍ.
اختر 1 أو 2 ثوابت تحميك من أخطاء حقيقية. غالبًا ما تكون الثوابت الجيدة عن الأمان (لا فقدان بيانات)، الاتساق (نفس المدخلات = نفس المخرجات)، أو الحدود (عدم تجاوز الحدود).
اكتب الثابت كجملة قصيرة، ثم قرر ما الدليل الذي يمكن لاختبارك ملاحظته: القيم المرجعة، البيانات المخزنة، الأحداث المنبعثة، أو استدعاءات التبعيات. التأكيدات القوية تتحقق من النتيجة والآثار الجانبية، لأن العديد من الأخطاء تختبئ في "أعاد OK لكنه كتب الشيء الخطأ."
على سبيل المثال، لديك دالة تطبق قسيمة على طلب:
الآن حوّلها إلى تأكيدات تقيس شيئًا ملموسًا:
expect(result.total).toBeGreaterThanOrEqual(0)
expect(db.getOrder(orderId).discountCents).toBe(originalDiscountCents)
تجنب التأكيدات الغامضة مثل "يعيد النتيجة المتوقعة". أكد القاعدة المحددة (غير سالب)، والأثر الجانبي المحدد (الخصم مخزن مرة واحدة).
لكل ثابت، أضف ملاحظة قصيرة في الاختبار عن أي بيانات ستنتهكه. هذا يحافظ على الاختبار من الانجراف إلى فحص مسار نجاح لاحقًا.
نمط بسيط صالح على المدى الطويل:
الاختبارات ذات الدلالة العالية غالبًا ما تؤكد أن الكود يفشل بأمان. إذا كان نموذج يولّد اختبارات مسارات النجاح فقط، فلن تتعلم الكثير عن سلوك الميزة عندما تصبح المدخلات والتبعيات فوضوية.
ابدأ بتحديد ما يعنيه "الفشل الآمن" لهذه الميزة. هل تعيد خطأً مهيكلًا؟ هل تعود إلى قيمة افتراضية؟ هل تعيد محاولة واحدة ثم تتوقف؟ اكتب ذلك في جملة واحدة، ثم اجعل الاختبارات تثبت ذلك.
عندما تطلب من Claude Code اختبارات أنماط الفشل، اجعل الهدف صارمًا: غطِّ الطرق التي يمكن أن ينكسر النظام بها، وآكد رد الفعل الذي تريده تمامًا. سطر مفيد: "أفضل القليل من الاختبارات ذات التأكيدات الأقوى على الكثير من الاختبارات السطحية."
فئات الفشل التي تميل لإنتاج أفضل الاختبارات:
مثال: لديك نقطة نهاية تنشئ مستخدمًا وتستدعي خدمة بريد إلكتروني لإرسال رسالة ترحيب. اختبار مسار النجاح الضعيف يتحقق من "يعيد 201". اختبار فشل ذو دلالة عالية يتحقق مما إذا كانت خدمة البريد تتوقف عن الاستجابة، فهل تنشئ المستخدم وتعيد 201 مع علامة "email_pending"، أم تعيد 503 ولا تنشئ المستخدم؟ اختر سلوكًا واحدًا، ثم أكد النتيجة والآثار الجانبية.
اختبر أيضًا ما الذي لا تتسربه. إذا فشل التحقق، تأكد من عدم كتابة شيء إلى قاعدة البيانات. إذا أعادت التبعية حمولة تالفة، تأكد من أنك لا ترمي استثناءً غير معالج أو تعيد تفاصيل مكدس الأخطاء الخام.
مجموعات الاختبارات منخفضة القيمة تحدث عادةً عندما يكافأ النموذج على الكم. إذا طلب موجهك "20 اختبارًا للوحدة"، تحصل غالبًا على تباينات صغيرة تبدو شاملة لكنها لا تكتشف شيئًا جديدًا.
الفخاخ الشائعة:
مثال: دالة "إنشاء مستخدم". عشر اختبارات لمسار النجاح قد تغير فقط سلسلة البريد الإلكتروني وتفشل في اختبار الأشياء المهمة: رفض عناوين البريد المكررة، التعامل مع كلمة مرور فارغة، وضمان أن معرفات المستخدم المرجعة فريدة ومستقرة.
حواجز تساعد في المراجعة:
تخيل ميزة واحدة: تطبيق رمز قسيمة عند الدفع.
العقد (صغير وقابل للاختبار): معطى إجمالي السلة بالسنت وقسيمة اختيارية، أعد مجموعًا نهائيًا بالسنت. القواعد: القسائم النسبية تقرب إلى الأسفل إلى أقرب سنت، القسائم الثابتة تخصم مبلغًا ثابتًا، والمجاميع لا تنخفض أبدًا عن 0. القسيمة قد تكون غير صالحة، منتهية، أو مستخدمة سابقًا.
لا تطلب "اختبارات لـ applyCoupon()" فقط. اطلب اختبار حالات الحدود، اختبارات أنماط الفشل، وثوابت مرتبطة بهذه العقدة.
اختر مدخلات تكسر الحساب أو التحقق: سلسلة قسيمة فارغة، subtotal = 0، subtotal أسفل أو فوق حد إنفاق أدنى، خصم ثابت أكبر من subtotal، ونسبة مثل 33% التي تحدث تقريبًا.
افترض أن بحث القسيمة قد يفشل وأن الحالة قد تكون خاطئة: خدمة القسيمة متوقفة، القسيمة منتهية، أو مُستردة من قبل هذا المستخدم. يجب أن يثبت الاختبار ماذا يحدث بعد ذلك (رفض القسيمة بخطأ واضح، المجموع دون تغيير).
مجموعة اختبارات صغيرة وذات دلالة (5 اختبارات) وما يكتشفه كل منها:
إن اجتازت هذه الاختبارات، فقد غطيت نقاط الانهيار الشائعة دون ملء المجموعة باختبارات مسار النجاح المتكررة.
قبل قبول ما يولده النموذج، قم بتمرير جودة سريع. الهدف اختبارات تحميك من خطأ محدد ومرجح.
استخدم هذه القائمة كحاجز:
حيلة عملية سريعة بعد التوليد: أعد تسمية الاختبارات إلى "should <behavior> when <edge condition>" و"should not <bad outcome> when <failure>". إذا لم تستطع إعادة تسميتها بسهولة، فهي غير مركزة.
إذا بنيت تطبيقات عبر الدردشة، نفّذ هذه الدورة داخل Koder.ai (koder.ai) حتى يعيش العقد، الخطة، والاختبارات المولدة في مكان واحد. عندما يغير إعادة الهيكلة السلوك بشكل غير متوقع، تسهل اللقطات والعودة مقارنة وتكرار حتى تبقى مجموعة الإشارة العالية مستقرة.
Default: aim for a small set that would catch a real bug.
A quick cap that works well is 6–10 tests per unit (function/module). If you need more, it usually means your unit is doing too much or your contract is unclear.
Happy-path tests mostly prove that your example still works. They tend to miss the stuff that breaks in production.
High-signal tests target:
Start with a tiny contract you can read in one breath:
Then generate tests from that contract, not from examples alone.
Test these first:
Pick one or two per input dimension so each test covers a unique risk.
A good failure-mode test proves two things:
If there’s a database write involved, always check what happened in storage after the failure.
Default approach: turn the invariant into an assertion on observable outcomes.
Examples:
expect(total).toBeGreaterThanOrEqual(0)Prefer checking both and , because many bugs hide in “returned OK but wrote the wrong thing.”
It’s worth keeping a happy-path test when it protects an invariant or a critical integration.
Good reasons to keep one:
Otherwise, trade it for boundary/failure tests that catch more classes of bugs.
Push for PHASE 1: plan only first.
Require the model to provide:
Only after you approve the plan should it generate code. This prevents “20 look-alike tests” output.
Default: mock only the boundary you don’t own (DB/network/clock), and keep everything else real.
To avoid over-mocking:
If a test breaks on refactor but behavior didn’t change, it’s often over-mocked or too implementation-coupled.
Use a simple deletion test:
Also scan for duplicates: