اختبار الطفرات بشرح مبسّط
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: PHPUnit PHPUnit Evidence: Test-backed
لمحة سريعة
قسم بعنوان «لمحة سريعة»تخبرك تغطية الأسطر أن سطرًا ما نُفِّذ أثناء مجموعة الاختبارات. لكنها لا تخبرك أن أي اختبار كان سيفشل لو كان ذلك السطر خاطئًا. يعالج اختبار الطفرات هذه الفجوة عبر إفساد الشيفرة عمدًا والتحقق مما إذا كانت الاختبارات تلاحظ ذلك. توضّح هذه الصفحة معنى درجة الطفرات، وكيف يستخدمها NextPDF أداةً تشخيصية، لا رقمًا للتباهي.
لماذا يهمّ هذا
قسم بعنوان «لماذا يهمّ هذا»التغطية من أكثر مقاييس الاختبار موثوقيةً، ومن أكثرها تضليلًا في الوقت نفسه. فالاختبار الذي يستدعي دالةً ولا يؤكّد أي شيء ينفّذ كل سطر فيها: تغطية كاملة، وكشف معدوم. تنصّ أدبيات المعايير صراحةً على أن ترتيب معايير التغطية لا يدل على قدرتها على كشف العيوب. هذه القدرة هي الخاصية التي تسمّيها فعالية الاختبار (ISO/IEC/IEEE 29119-4، §C.2.4). نسبة التغطية وضمان العثور على العيوب ادّعاءان مختلفان.
بالنسبة إلى محرّك PDF، فهذا ليس أمرًا نظريًا. ففحص نطاق بايتات التوقيع، أو إزاحة المرجع المتقاطع، أو فرع ترميز — يمكن للاختبارات أن “تغطّي” كل ذلك تمامًا دون أن تؤكّد أبدًا القيمة المهمة. مجموعة اختبارات خضراء فوق اختبارات ضعيفة أسوأ من فجوة صريحة، لأنها تثبّط فعليًا أي شخص عن البحث.
الخلاصة المختصرة
قسم بعنوان «الخلاصة المختصرة»- اختبار الطفرات يُجري آلاف التعديلات الصغيرة المتعمّدة (الطفرات) على الشيفرة — قلب
<إلى<=، و+إلى-، وقيمةreturn— ثم يعيد تشغيل الاختبارات على كل طفرة. - إذا فشل اختبار بسبب طفرة، فإن الطفرة مقتولة: هناك اختبار أكّد ذلك السلوك فعليًا. وإذا ظلّت جميع الاختبارات ناجحة، فإن الطفرة هربت: نُفِّذ السلوك لكنه لم يُفحص قط.
- مؤشر درجة الطفرات (MSI) هو، تقريبًا، نسبة الطفرات المقتولة إلى إجمالي الطفرات غير المتكافئة. وهو يقيس ما إذا كانت اختباراتك تكشف التغييرات، لا ما إذا كانت تنفّذ الشيفرة.
- بعض الطفرات متكافئة — لا يمكنها تغيير السلوك القابل للملاحظة، لذا لا يستطيع أي اختبار قتلها. احتساب هذه إخفاقات أمر غير نزيه. يثبت NextPDF هذه الطفرات ويسجّلها في سجلّ بدلًا من استبعادها بصورة غير رسمية.
- يستخدم NextPDF مؤشر MSI للعثور على الاختبارات الضعيفة وتقويتها. إنه بوابة تشخيصية في التكامل المستمر، لا رقمًا تسويقيًا.
كيف يتعامل NextPDF معه
قسم بعنوان «كيف يتعامل NextPDF معه»تُشغَّل الطفرات على المحرّك باستخدام مُطفِّر Infection. وهو مُهيّأ على شجرة المصدر الإنتاجية، مع تفعيل عائلات المُطفّرات الحسابية، والمنطقية، وحدود الشروط، والمساواة، وقيمة الإرجاع، والإزالة — وهي بالضبط العوامل التي تكشف المنطق “المنفَّذ لكن غير المؤكَّد”. والتدفّق آلي:
- Start green The suite must pass before mutation begins.
- Mutate Apply one small, deliberate change to the source.
- Re-run Run the tests that cover the mutated line.
- Killed A test failed — the behaviour is genuinely asserted.
- Escaped All tests still pass — a weak spot to strengthen.
- Equivalent No test can kill it because behaviour is unchanged — proven and ledgered, not scored as a miss.
خياران تصميميان يجعلان الرقم جديرًا بالثقة. أولًا، الدرجة موصولة بوصفها بوابة. يفرض التكامل المستمر حدًا أدنى لمؤشر MSI (وحدًا أدنى لمؤشر MSI المُغطّى) ويشغّل صيغةً محصورة بالفروق على الأسطر المتغيّرة. ونتيجةً لذلك، فإن أي تغيير يضيف شيفرة دون تأكيدات حقيقية يُلتقط عند المراجعة، لا بعد ذلك. ثانيًا، لا يستبعد NextPDF الطفرات المزعجة بصمت. أما الطفرات المتكافئة دلاليًا بحق — مثل !== مقابل != عندما يضمن التنميط الصارم أن كلا المعاملين من النوع نفسه — فتُسجَّل في سجلّ طفرات مع اختبار صريح لإثبات التكافؤ. ونتيجةً لذلك، يعكس عدد الطفرات الهاربة فجوات حقيقية، لا مجرّد ضبط حسابات. PHPStan المستوى 10 إضافةً إلى strict_types إضافةً إلى الخصائص المنمَّطة هو ما يجعل تلك الإثباتات على التكافؤ سليمة.
ماذا تقول الأدلّة
قسم بعنوان «ماذا تقول الأدلّة»Evidence: Test-backed اختبار الطفرات مُهيّأ في المحرّك على أدلة المصدر الإنتاجية مع تفعيل عائلات المُطفّرات الكاشفة للسلوك. وهو مفروض بوصفه بوابة تكامل مستمر بحدّ أدنى لمؤشر MSI وصيغة محصورة بالفروق. إنه فحص بناء، لا أمرًا ثانويًا يُؤجَّل.
Evidence: Test-backed تُعالَج مشكلة الطفرات المتكافئة بنزاهة. تُصنَّف الطفرات المتكافئة دلاليًا وتُدعَم باختبارات مخصّصة لإثبات التكافؤ في سجلّ طفرات، مع ارتكاز سلامة كل إثبات على PHPStan المستوى 10 إضافةً إلى التنميط الصارم. ومن ثَمّ يمثّل عدد الطفرات الهاربة سلوكًا حقيقيًا غير مكتشَف، لا ضوضاء غير قابلة للقتل مُضخَّمة لتبدو الدرجة أسوأ مما هي عليه.
Evidence: Standard-backed الطفرات تقنية معترَف بها، لا من ابتكار NextPDF. Spec: ISO/IEC/IEEE 29119-4, §B.2.4 ISO/IEC/IEEE 29119-4 §B.2.4 يصف تطبيق طفرات عامة على عناصر مواصفة لاشتقاق طفرات محدّدة للاختبار. والتقنية لازمة أصلًا لأن المعيار نفسه ينصّ على أن ترتيب الاحتواء بين معايير التغطية لا يرتّبها بحسب القدرة على كشف العيوب (ISO/IEC/IEEE 29119-4، §C.2.4).
Evidence: Standard-backed التغطية نفسها معرّفة جيدًا ومحدودة. Spec: PHPUnit PHPUnit يميّز بين تغطية الأسطر والفروع والمسارات في التغطية. فتغطية الأسطر لا تسجّل سوى أن سطرًا قابلًا للتنفيذ قد نُفِّذ. ومعرفة التعريف هي ما يجعل عدم كفايتها بديهيًا.
مثال عملي
قسم بعنوان «مثال عملي»المهمّ ليس الأمر نفسه — بل ما تكشفه لك الطفرة الهاربة:
<?php
declare(strict_types=1);
final class ByteRange{ // Suppose the production guard is: // if ($offset < 0) { throw new InvalidByteRange(); } public function assertNonNegative(int $offset): void { if ($offset < 0) { throw new InvalidByteRange('offset must be >= 0'); } }}
// A test that EXECUTES this line but does not assert the boundary:// $byteRange->assertNonNegative(5); // no exception expected, none asserted// gives 100% line coverage of assertNonNegative().//// Mutation flips `< 0` to `<= 0`. Behaviour now differs ONLY at $offset === 0.// If no test passes 0 and asserts what happens, every test still passes:// the mutant ESCAPED. Coverage said "tested"; mutation said "the boundary// is unasserted". The fix is a test that pins offset === 0, not a higher// target.//// composer mutation:diff → mutate only changed lines, enforce min MSI// composer mutation:full → full-tree mutation gateتلك الطفرة الهاربة هي القيمة المضافة بأكملها. لقد حدّدت تأكيدًا مفقودًا حقيقيًا ومحدّدًا كان تقرير التغطية قد عدّه مُختبَرًا بالكامل.
مفهوم خاطئ شائع
قسم بعنوان «مفهوم خاطئ شائع»المفهوم الخاطئ الأبرز هو أن درجة الطفرات علامة يجب تعظيمها. مؤشر MSI مرتفع جدًا يُحقَّق بكتابة اختبارات لقتل الطفرات أجوف تمامًا مثل تغطية مرتفعة تُحقَّق باستدعاء الدوال دون تأكيد. فقد جرى التلاعب بالمقياس، ولم يعد يقيس الكشف. يستخدم NextPDF مؤشر MSI لـالعثور على الاختبارات الضعيفة. والمُخرَج هو تأكيد أفضل؛ والتباهي ليس الغرض صراحةً.
المفهوم الخاطئ الثاني هو أن كل طفرة ناجية عيب في الاختبارات. بعض الطفرات متكافئة بحق ولا يمكن قتلها بأي اختبار، لأنها لا تغيّر السلوك القابل للملاحظة. ومعاملة هذه إخفاقات تنتج درجة منخفضة بصورة مصطنعة وغير نزيهة، وتدرّب الناس على تجاهل التقرير. نهج NextPDF هو إثبات التكافؤ صراحةً وتسجيله في السجلّ، لا كبته بصمت أو التظاهر بأن الرقم أسوأ مما هو عليه.
الحدود والقيود
قسم بعنوان «الحدود والقيود»يقيس اختبار الطفرات ما إذا كانت الاختبارات تكشف التغييرات المحقونة. وهو لا يثبت أن الشيفرة صحيحة. وهو لا يقيس الأداء أو المطابقة. ولا يمكنه قتل طفرة متكافئة حقًا. إن درجة الطفرات الحالية، والحدّ الأدنى لمؤشر MSI المعمول به، وعدد المتكافئات المسجَّلة، وأي رقم تغطية هي إشارات جودة حيّة تُولَّد من مُخرجات التكامل المستمر وتُنشر مع البناء. وهي غائبة هنا عمدًا، لأن أي رقم يُلصَق في نصّ يصبح قديمًا ويتحوّل إلى كذبة صغيرة. الحقيقة الثابتة الوحيدة التي تذكرها هذه الصفحة هي PHPStan المستوى 10، وهي خاصية تهيئة ترتكز عليها إثباتات التكافؤ، لا قياس.
اختيار المُطفّرات والعتبات وسياسة السجلّ مملوكة لتهيئة الطفرات في المحرّك وقد تتطوّر. وتلك التهيئة هي المرجع إن اختلفت يومًا مع هذه الصفحة. ولا يُقدَّم هنا أي ادّعاء بشأن فعالية اختبار أي مكتبة أخرى.
مستندات ذات صلة
قسم بعنوان «مستندات ذات صلة»- هرم اختبار NextPDF — الطبقات الخمس التي يدقّق اختبار الطفرات اختباراتها للتأكد من أنها تكشف العيوب فعليًا.
- الأنواع الصارمة، في كل مكان — كيف يجعل PHPStan المستوى 10 والتنميط الصارم إثباتات الطفرات المتكافئة سليمة.
- اختبار الملفات الذهبية — طبقة أخرى تساعد اختبار الطفرات على التحقق من القدرة على الكشف.
مسرد المصطلحات
قسم بعنوان «مسرد المصطلحات»- الطفرة — تغيير صغير واحد متعمّد على الشيفرة، يُستخدم لاختبار ما إذا كانت مجموعة الاختبارات ستلاحظ ذلك التغيير.
- الطفرة المقتولة — طفرة جعلت اختبارًا واحدًا على الأقل يفشل؛ فقد أُكّد السلوك فعلًا.
- الطفرة الهاربة — طفرة تركت كل اختبار ناجحًا. نُفِّذ السلوك لكنه لم يُؤكَّد قط — نقطة ضعف يجب إصلاحها.
- الطفرة المتكافئة — طفرة لا يمكنها تغيير السلوك القابل للملاحظة، لذا لا يستطيع أي اختبار قتلها. يثبت NextPDF هذه الطفرات ويسجّلها في السجلّ.
- MSI (مؤشر درجة الطفرات) — تقريبًا، الطفرات المقتولة مقسومة على إجمالي الطفرات غير المتكافئة؛ مقياس للكشف، لا للتنفيذ.
- تغطية الأسطر — مقياس لا يسجّل سوى أن سطرًا قابلًا للتنفيذ قد نُفِّذ أثناء المجموعة؛ مُعرَّف بواسطة PHPUnit، وغير كافٍ بمفرده.