لا يوجد الكثير من الاختبارات - الجميع يعرف ذلك. لم تعد المذكرات حول اختبار الوحدة والتكامل ممتعة للغاية. لكننا ما زلنا لا نعرف ما إذا كان من الممكن الاعتماد على نتائج اجتياز الاختبارات ، وما هي النسبة المئوية للتغطية التي ستسمح لنا بعدم السماح للأخطاء في الإنتاج. إذا كانت التغييرات القاتلة في اختبارات تخطي الشفرة ، دون التأثير على نتائجها ، فإن الحل يقترح نفسه - فأنت بحاجة إلى اختبار الاختبارات!

كان النهج لأتمتة هذه المهمة تقرير مارك لانجوفوي في Frontend
Conf . الفيديو والمقال قصيران ، والأفكار مفيدة للغاية - تحتاج إلى تدوين الملاحظات.
حول المتحدث: يعمل Mark
Langovoi (
marklangovoi ) في Yandex في مشروع
Yandex.Tolok . هذا هو منصة التعهيد الجماعي لترميز كميات كبيرة من البيانات بسرعة. يقوم العملاء بتنزيل البيانات التي تحتاج ، على سبيل المثال ، للتحضير لاستخدامها في خوارزميات التعلم الآلي ، وتحديد السعر ، وعلى الجانب الآخر ، يمكن لفناني الأداء إكمال المهام وكسب المال.
في وقت فراغه ، طور مارك أيام مطوري Krasnodar Devodar للمطورين ، وهي واحدة من 19
مجتمعًا لتكنولوجيا المعلومات دعاهم نشطاءها إلى Frontend Conf في موسكو.
الاختبار
هناك أنواع مختلفة من الاختبارات الآلية.

أثناء
اختبار الوحدة الشائعة
، نكتب اختبارات لأجزاء صغيرة (وحدات) من التطبيق. من السهل الكتابة ، ولكن في بعض الأحيان أثناء التكامل مع الوحدات الأخرى قد لا يتصرفون تمامًا كما توقعنا.
لتجنب ذلك ، يمكننا كتابة
اختبارات التكامل التي ستختبر تشغيل وحداتنا معًا.

إنها أكثر تعقيدًا قليلاً ، لذلك سنركز اليوم على اختبار الوحدة.
اختبار الوحدة
أي مشروع يريد على الأقل القليل من الاستقرار هو كتابة اختبارات الوحدة.
تأمل في مثال.
class Signal { on(callback) { ... } off(callback) { const callbackIndex = this.listeners.indexOf(callback); if (callbackIndex === -1) { return; } this.listeners = [ ...this.listeners.slice(0, callbackIndex - 1), ...this.listeners.slice(callbackIndex) ]; } trigger() { ... } }
هناك فئة Signal - هذا هو Event Emitter ، الذي يحتوي على طريقة تشغيل للاشتراك وطريقة إيقاف لحذف الاشتراك - نتحقق مما إذا كان رد الاتصال موجودًا في صفيف المشتركين ، ثم نحذفه. وبالطبع ، هناك طريقة تشغيل لاستدعاء عمليات الاستدعاء الموقعة.
لدينا اختبار بسيط لهذا المثال الذي يستدعي طرق التشغيل والإيقاف ، ثم المشغل ، للتحقق من عدم استدعاء المكالمة بعد إلغاء الاشتراك.
test('off method should remove listener', () => { const signal = new Signal(); let wasCalled = false; const callback = () => { wasCalled = true; }; signal.on(callback); signal.off(callback); signal.trigger(); expect(wasCalled).toBeFalsy(); });
معايير تقييم الجودة
ما هي معايير تقييم جودة مثل هذا الاختبار؟
إن تغطية الكود هي المعيار الأكثر شيوعًا والمعروف الذي يُظهر عدد النسبة المئوية من سطور الكود التي تم تنفيذها عند تشغيل الاختبار.

قد يكون لديك 70٪ أو 80٪ أو كل تغطية الرمز 90٪ ، ولكن هل يعني هذا أنه عند جمع البناء التالي للإنتاج ، سيكون كل شيء على ما يرام ، أو قد يحدث خطأ ما؟
دعنا نعود إلى مثالنا.
مساء الجمعة ، أنت متعب ، وتنتهي من الميزة التالية. ثم تصادف هذا الرمز الذي كتبه زميلك. شيء عنك بدا معقدًا ومخيفًا لك.
...this.listeners.slice(0, callbackIndex - 1), ...this.listeners.slice(callbackIndex)
لقد قررت أنه ربما يمكنك مسح الصفيف فقط:
class Signal { ... off(callback) { const callbackIndex = this.listeners.indexOf(callback); if (callbackIndex === -1) { return; } this.listeners = []; } ... }
لقد التزمت وجمعت المشروع وأرسلته إلى الإنتاج. مرت الاختبارات - لماذا لا؟ وذهب للراحة في حانة.

ولكن فجأة ، في وقت متأخر من الليل ، رنّت مكالمة على جهاز الاستقبال ، وأن كل شيء كان ينخفض ، ولم يتمكن الناس من استخدام المنتج ، وبشكل عام ، أهدرت الأعمال المال! تحترق ، أنت مهدد بالفصل.

كيف تتعامل مع هذا؟ ماذا تفعل بالاختبارات؟ كيفية التقاط مثل هذه الأخطاء الغبية البدائية؟ من سيختبر الاختبارات؟
بالطبع ، يمكنك توظيف جيش من مهندسي ضمان الجودة - دعهم يجلسوا ويصفقوا لتطبيقنا.

أو استئجار أتمتة ضمان الجودة. يمكن إلقاء اللوم عليهم في اختبارات الكتابة - لماذا تكتب بنفسك إذا كان هناك أشخاص مميزون لهذا؟
لكن في الواقع إنها مكلفة ، لذا سنتحدث اليوم عن التحليل الطفري أو الاختبار الطفري.
اختبار الطفرة
هذه طريقة لأتمتة عملية اختبار اختباراتنا. والغرض منه هو تحديد الاختبارات غير الفعالة وغير المكتملة ، وهذا هو في الواقع
اختبارات الاختبار .
تتمثل الفكرة في تغيير أجزاء من التعليمات البرمجية ، وإجراء اختبارات عليها ، وإذا لم تسقط الاختبارات ، فهي غير مكتملة.
يتم إجراء التغييرات باستخدام عمليات معينة -
الطفرات . يستبدلون ، على سبيل المثال ، بالإضافة إلى ناقص ، ويضربون بالقسمة ، وعمليات أخرى مماثلة. يمكن للموترات تغيير أجزاء من الكود ، واستبدال الشروط في حين ، صفر صفائف بدلاً من إضافة بعض العناصر إلى الصفيف.

نتيجة لتطبيق الطفرات على شفرة المصدر ، فإنه يتحول ويصبح
متحولة .
ينقسم المسوخ إلى فئتين:
- قتل - تلك التي تمكنا من التعرف على الانحرافات ، أي التي وقع عليها اختبار واحد على الأقل.
- الناجون هم الذين هربوا منا وأوصلوا الخلل إلى الإنتاج.
لتقييم الجودة ، هناك مقياس
MSI (مؤشر درجة التحور) - النسبة المئوية للطفرات الميتة والبقاء على قيد الحياة. كلما زاد الفرق بين اختبارات تغطية الكود و MSI ، كلما زادت النسبة المئوية لتغطية الكود تعكس مدى صلة اختباراتنا.
كان هذا قليلًا من الناحية النظرية ، والآن فكر في كيفية استخدامه في JavaScript.
حل جافا سكريبت
لا يوجد سوى أداة اختبار تطوير طفرة واحدة نشطة في JavaScript -
Stryker . تم إعطاء هذا الاسم للأداة تكريماً لشخصية X-man William Stryker - خالق "سلاح X" ومقاتل مع جميع المسوخ.

Stryker ليس عداء اختبار مثل Karma أو Jest ؛ ولا هو إطار اختبار مثل موكا أو ياسمين. هذا هو إطار اختبار الطفرة الذي يكمل البنية التحتية الحالية الخاصة بك.
نظام البرنامج المساعد
Stryker مرنة للغاية ، مبنية بالكامل على نظام توصيل ، ومعظمها مكتوب بواسطة مطوري Stryker.

هناك مكونات إضافية لتشغيل الاختبارات على Jest و Karma و Mocha. هناك تكامل مع الأطر Mocha (stryker-mocha-framework) Jasmine (stryker-jasmine) ومجموعات الطفرات الجاهزة لجافا سكريبت و TypeScript وحتى لـ Vue:
- stryker-javascript-mutator ؛
- stryker-typcript.
- stryker-vue-mutator.
يتم تضمين Mutators for React في stryker-javascript-mutator. بالإضافة إلى ذلك ، يمكنك دائمًا كتابة الطفرات الخاصة بك.
إذا كنت بحاجة إلى تحويل الرمز قبل التشغيل ، فيمكنك استخدام المكونات الإضافية لـ Webpack أو Babel أو TypeScript.

يتم إعداد كل هذا ببساطة نسبيًا.
التكوين
التكوين ليس صعبًا: ما عليك سوى تحديد في JSON config أي عداء الاختبار (و / أو إطار الاختبار و / أو ناقل الحركة) الذي تستخدمه ، بالإضافة إلى تثبيت المكونات الإضافية المناسبة من npm.
تستطيع أداة
stryker-cli المساعدة لوحدة التحكم البسيطة القيام بكل هذا نيابة عنك في وضع السؤال والجواب. سوف تسألك عما تستخدمه ، وستقوم بتكوين نفسها.
كيف يعمل
دورة الحياة بسيطة وتتكون من الخطوات التالية:
- قراءة وتحليل التكوين. يقوم Stryker بتنزيل التكوين وتحليله لمختلف المكونات الإضافية والإعدادات واستبعاد الملف وما إلى ذلك.
- قم بتنزيل المكونات الإضافية وفقًا للتكوين.
- تشغيل الاختبارات على شفرة المصدر للتحقق مما إذا كانت الاختبارات ذات صلة الآن (فجأة تم كسرها بالفعل).
- إذا كان كل شيء على ما يرام ، يتم إنشاء مجموعة من المسوخ من الملفات التي سمحنا بتحويلها.
- إجراء الاختبارات على المسوخ.

أعلاه مثال على بدء Stryker:
- يبدأ Stryker ؛
- يقرأ التكوين ؛
- يحمّل التبعيات اللازمة ؛
- يجد الملفات التي سوف تتحول.
- إجراء اختبارات على شفرة المصدر ؛
- يخلق 152 طفرة.
- تشغيل الاختبارات في 8 سلاسل (في هذه الحالة ، بناءً على عدد نوى وحدة المعالجة المركزية).
هذه ليست عملية سريعة ، لذا من الأفضل القيام بذلك على بعض خوادم CI / CD.
بعد اجتياز جميع الاختبارات ، يقدم سترايكر تقريرًا موجزًا عن الملفات مع عدد الطفرات التي تم إنشاؤها وقتلها والبقاء على قيد الحياة ، بالإضافة إلى النسبة المئوية لنسبة الطفرات الميتة إلى الناجين (MSI) والمطفرات التي تم استخدامها.
هذه مشاكل محتملة لم تكن متوقعة في اختباراتنا.
لتلخيص
اختبار الطفرة مفيد ومثير للاهتمام . يمكن أن يجد مشاكل في المراحل الأولى من الاختبار ، وبدون مشاركة الناس. سيقلل الوقت اللازم للتحقق من صحة طلب السحب ، على سبيل المثال ، نظرًا لأن المطورين المؤهلين لن يضطروا إلى قضاء بعض الوقت في التحقق من طلب السحب ، والذي يحتوي بالفعل على مشاكل محتملة. أو احفظ الإنتاج إذا قررت إعداد إصدار جديد ليلة الجمعة.
Stryker هي أداة اختبار طفرة مرنة متعددة الخيوط. وهي تتطور بنشاط ، لكنها لم تصل حتى الآن إلى النسخة الرئيسية. على سبيل المثال ، أثناء إعداد هذا التقرير ، جعل مطوروها أخيرًا من الممكن في البرنامج المساعد لـ Babel تحديد ملف التكوين وإصلاح تكامل Jest. هذا
مشروع مفتوح المصدر يمكن المساعدة في تطويره.
التعليمات- كيف تختبر اختبارات الطفرة؟ بالتأكيد ، هناك أيضًا خطأ. في المثال الأول لاختبار الوحدة ، كانت التغطية 90٪. يبدو أن كل شيء على ما يرام ، ولكن لا تزال الحالات تراجعت عندما سقط كل شيء واشتعلت فيه النيران. وبالتالي ، لماذا يجب أن يكون هناك شعور بأن كل شيء على ما يرام بعد تغطية هذه الاختبارات الطفرية؟- أنا لا أقول أن اختبار الطفرة هو رصاصة فضية وسوف يعالج كل شيء. بطبيعة الحال ، قد تكون هناك بعض الحالات الجنونية الحدودية أو عدم وجود نوع من الطفرات. بادئ ذي بدء ، يتم اكتشاف الأخطاء النموذجية بسهولة. على سبيل المثال ، قمت بوضع شيك على العمر ، وقمت بتعيينه على <18 (كان من الضروري <=) ، وفي الاختبار نسيت إجراء فحص حالة الحدود. لقد أجريت مقارنة أخرى مع المتحور ، ونتيجة لذلك ، سقط الاختبار (أو لم يسقط) ، وتفهم أن كل شيء جيد أو كل شيء سيئ. يتم القبض على هذه الأشياء بسرعة. هذه طريقة لإلحاق الاختبارات بشكل صحيح ، والعثور على النقاط المفقودة.
- في كثير من الأحيان لديك حالة من "الذهول واليسار"؟ أعتقد أن هذا غير صحيح.- لا ، ولكن أعتقد أن مثل هذه الأشياء موجودة في العديد من المشاريع. بطبيعة الحال ، هذا ليس صحيحا. يعتقد الكثير من الناس أن تغطية الرمز تساعد على التحقق من كل شيء ، يمكنك المغادرة بأمان ولا تقلق - ولكن هذا ليس كذلك.
- سأقول على الفور ما هي المشكلة. لدينا الكثير من جميع أنواع المخفضات والأشياء الأخرى التي نختبرها طفراتيا ، وهناك الكثير منها. كل هذا ينمو ، وتبين أنه لكل طلب سحب ، يتم إطلاق اختبار الطفرة ، الأمر الذي يستغرق الكثير من الوقت. هل من الممكن الركض فقط على ما تغير؟"أعتقد أنه يمكنك تكوينه بنفسك." على سبيل المثال ، من جانب المطور ، عندما يضغط ، يلتزم ، يمكنك إنشاء مكون إضافي على
مراحل يتم تشغيل الملفات التي تغيرت فقط. هذا ممكن على CI / CD. في حالتنا ، المشروع كبير جدًا وقديم ، ونحن نمارس الاختبار الفوري. نحن لا نتحقق من كل شيء ، لأنه سيستغرق أسبوعًا ، سيكون هناك مئات الآلاف من الطفرات. أوصي بإجراء عمليات فحص مفاجئة ، أو تنظيم عملية بدء تشغيل انتقائية بنفسي. لم أر أداة جاهزة لهذا التكامل.
- هل اكتمال جميع الطفرات الممكنة لقطعة معينة من التعليمات البرمجية مضمونة؟ إذا لم يكن كذلك ، كيف يتم تحديد الطفرات بالضبط؟- أنا شخصياً لم أتحقق ، لكني لم أواجه أي مشاكل مع هذا أيضًا. يجب أن يُولِّد Stryker جميع الطفرات الممكنة على نفس قطعة الشفرة.
- أريد أن أسأل عن اللقطات. يختبر اختبار الوحدة الخاصة بي كلاً من المنطق ، بما في ذلك تخطيط مكون رد فعل اللقطة. بطبيعة الحال ، إذا قمت بتغيير أي تصميم منطقي ، فإن تخطيطي سيتغير هناك. هذا سلوك متوقع ، أليس كذلك؟- نعم ، هذا معناه ، أن تقوم بتحديث اللقطات يدويًا.
- إذن أنت تتجاهل اللقطات في هذا التقرير بطريقة أو بأخرى؟- على الأرجح ، يجب تحديث اللقطات مقدمًا ، ثم إجراء اختبار الطفرة ، وإلا سيكون هناك الكثير من القمامة من Stryker.
- سؤال حول خوادم CI. بالنسبة للاختبارات البسيطة للوحدات ، يوجد مراسلون ، تحت GitLab ، لأي شيء تريده ، يعرضون النسبة المئوية للاختبارات الناجحة ، ويمكنك تكوين ما إذا كنت ستفشل أم لا. ماذا عن سترايكر؟ إنه يعرض الجهاز اللوحي فقط في وحدة التحكم ، ولكن ماذا أفعل بعد ذلك؟- لديهم مراسل HTML ، يمكنك جعل المراسلين الخاصين بك - كل شيء قابل للتخصيص بمرونة. ربما توجد بعض الأدوات المحددة ، ولكن نظرًا لأننا ما زلنا نجري اختبار طفرة النقاط ، لم أجد تكاملات محددة مع TeamCity وأدوات CI / CD المماثلة.
- إلى أي مدى تزيد اختبارات الطفرة من دعم الاختبارات التي تجريها بشكل عام؟ أي أن الاختبارات مؤلمة ، ويجب إعادة كتابة الاختبارات عندما تتم إعادة كتابة الرمز ، وما إلى ذلك. في بعض الأحيان يكون إعادة كتابة الرمز أسهل من الاختبارات في بعض الأحيان. وهنا لدي أيضًا اختبارات طفرية. ما هي تكلفة الأعمال؟- أولاً ، ربما سأصحح أن إعادة كتابة التعليمات البرمجية من أجل الاختبارات خاطئة. يجب أن يكون الرمز سهل الاختبار. أما بالنسبة لما يجب استكماله ، فمن المهم مرة أخرى أن تكون الاختبارات كاملة وفعالة قدر الإمكان. إذا لم تكن كاملة ، فهذا يعني أنه قد يحدث خطأ يؤدي إلى خسائر. بطبيعة الحال ، يمكنك اختبار الأجزاء الأكثر أهمية فقط للأعمال.
"ومع ذلك ، ما هي التكلفة الباهظة التي تظهر عندما تظهر اختبارات الطفرة ، مما لو لم تكن هناك."- إنها مثل الاختبارات السيئة الآن. إذا كانت الاختبارات مكتوبة بشكل سيء الآن ، فسيتعين عليك إضافة الكثير. سيجد اختبار الطفرة الحالات التي لا تغطيها الاختبارات.
- على الشريحة مع نتائج فحص Stryker ، هناك الكثير من vorings ، فهي حرجة أو غير حرجة. كيفية التعامل مع الإيجابيات الكاذبة؟- السؤال الخفي هو ما يعتبر خطأ. سألت الرجال في فريقنا عما حدث لهم من أشياء مثيرة للاهتمام. كان هناك مثال حول نص الخطأ. أفاد سترايكر أن الاختبارات لم تستجب لتغيير نص الخطأ. يبدو أن دعامة ، لكنها طفيفة.
- إذن ترى مثل هذه الأخطاء وتتخطى الأخطاء غير الحرجة في الوضع اليدوي؟"لدينا فحص مفاجئ ، لذلك نعم."
- لدي سؤال عملي. عند تنفيذ ذلك ، ما هي نسبة الاختبارات التي فشلت فيها؟- لم ننفذها على المشروع بأكمله ، ولكن كانت هناك مشاكل بسيطة في المشروع الجديد. لذلك ، لا أستطيع أن أقول الأرقام الدقيقة ، ولكن بشكل عام ، أدى النهج بالتأكيد إلى تحسين الوضع.
شاهد عروض أداء أمامية أخرى مفيدة بنفس القدر على قناتنا على YouTube ، حيث تصل جميع التقارير المواضيعية من جميع مؤتمراتنا تدريجيًا إلى هناك. أو اشترك في النشرة الإخبارية ، وسوف نبقيك على علم بجميع المواد الجديدة وأخبار المؤتمرات المستقبلية.