الاختبارات غير المستقرة: التخلص من كابوس حي في الاختبار

نشرت: 2022-03-10
ملخص سريع ↬ تعد الاختبارات غير الموثوق بها كابوسًا حيًا لأي شخص يكتب الاختبارات الآلية أو ينتبه إلى النتائج. حتى أن الاختبارات غير المستقرة تسببت في كوابيس وليال بلا نوم للناس. في هذا المقال ، تشارك Ramona Schwering تجاربها لمساعدتك على الخروج من هذا الجحيم أو تجنب الدخول فيه.

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

من الأفضل تلخيص عبرة القصة من قبل المؤلف نفسه:

"الكذاب لا يؤمن حتى عندما يقول الحق".

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

اختبار الواجهة الأمامية: لماذا تهتم أيضًا؟

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

يجدر بنا أن نتذكر ما يعنيه اختبار الواجهة الأمامية. في جوهره ، يعد اختبار الواجهة الأمامية مجموعة من الممارسات لاختبار واجهة المستخدم لتطبيق ويب ، بما في ذلك وظائفه.

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

علم الاختبارات غير المستقرة

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

عندما أتذكر كوابيس الاختبار التي مررت بها ، تتبادر إلى ذهني حالة واحدة على وجه الخصوص. كان في اختبار واجهة المستخدم. قمنا ببناء مربع تحرير وسرد مصمم خصيصًا (أي قائمة قابلة للتحديد مع حقل إدخال):

مثال على محدد مخصص
محدد مخصص في مشروع عملت عليه كل يوم. (معاينة كبيرة)

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

تُظهر لقطة شاشة الفشل عدم تصفية قائمة النتائج ، على الرغم من نجاح البحث:

لقطة شاشة من تنفيذ CI باختبار غير مستقر
اختبار غير مستقر أثناء العمل: لماذا فشل في بعض الأحيان فقط وليس دائمًا؟ (معاينة كبيرة)

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

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

مشكلة أخرى مهمة في الاختبارات غير المستقرة هي الموقف الذي تضفيه فينا نحن المطورين. عندما بدأت العمل في أتمتة الاختبار ، كثيرًا ما سمعت المطورين يقولون هذا ردًا على اختبار فاشل:

"آه ، هذا البناء. لا تهتم ، فقط اطلقها مرة أخرى. سوف يمر في نهاية المطاف ، في وقت ما ".

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

المزيد بعد القفز! أكمل القراءة أدناه ↓

الاسباب

لذا ، فإن الاختبارات غير المستقرة تمثل مشكلة. ماذا يجب ان نفعل حيالهم؟ حسنًا ، إذا عرفنا المشكلة ، يمكننا تصميم استراتيجية مضادة.

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

في الأقسام التالية ، سوف نستعرض أكثر الأقسام شيوعًا التي صادفتها.

1. أسباب جانب الاختبار

في عالم مثالي ، يجب أن تكون الحالة الأولية لتطبيقك أصلية ويمكن التنبؤ بها بنسبة 100٪. في الواقع ، لا تعرف أبدًا ما إذا كان المعرف الذي استخدمته في اختبارك سيكون دائمًا هو نفسه.

دعونا نفحص مثالين لفشل واحد من جانبي. الخطأ الأول هو استخدام معرف في تركيبات الاختبار الخاصة بي:

 { "id": "f1d2554b0ce847cd82f3ac9bd1c0dfca", "name": "Variant product", }

كان الخطأ الثاني هو البحث عن محدد فريد لاستخدامه في اختبار واجهة المستخدم والتفكير ، "حسنًا ، هذا المعرف يبدو فريدًا. سأستخدمه ".

 <!-- This is a text field I took from a project I worked on --> <input type="text" />

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

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

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

ومع ذلك ، لا تنس أن الاختبارات تدور حول تحدي الافتراضات . ماذا يحدث إذا كانت افتراضاتك معيبة في البداية؟ لقد واجهت هذه في كثير من الأحيان ، المفضل لدي هو الافتراضات المعيبة حول الوقت.

أحد الأمثلة على ذلك هو استخدام أوقات انتظار غير دقيقة ، لا سيما في اختبارات واجهة المستخدم - على سبيل المثال ، باستخدام أوقات انتظار ثابتة . السطر التالي مأخوذ من اختبار Nightwatch.js.

 // Please never do that unless you have a very good reason! // Waits for 1 second browser.pause(1000);

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

الافتراضات الخاطئة لا تتوقف عند هذا الحد. يمكن أن يكون لدينا أيضًا افتراضات خاطئة حول ترتيب البيانات . تخيل شبكة أو قائمة تحتوي على إدخالات متعددة بمعلومات ، مثل قائمة العملات:

عنصر قائمة مخصص مستخدم في مشروعنا
عنصر قائمة مخصص مستخدم في مشروعنا. (معاينة كبيرة)

نريد العمل بمعلومات الإدخال الأول ، عملة "الكورونا التشيكية". هل يمكنك التأكد من أن تطبيقك سيضع دائمًا قطعة البيانات هذه على أنها الإدخال الأول في كل مرة يتم فيها تنفيذ اختبارك؟ هل يمكن أن تكون "اليورو" أو عملة أخرى هي أول دخول في بعض المناسبات؟

لا تفترض أن بياناتك ستأتي بالترتيب الذي تحتاجه. على غرار المعرفات المشفرة ، يمكن أن يتغير الطلب بين الإصدارات ، اعتمادًا على تصميم التطبيق.

2. الأسباب البيئية

تتعلق الفئة التالية من الأسباب بكل شيء خارج اختباراتك. على وجه التحديد ، نحن نتحدث عن البيئة التي يتم فيها تنفيذ الاختبارات ، والاعتماد على CI و Docker ذات الصلة خارج اختباراتك - كل تلك الأشياء التي بالكاد يمكنك التأثير عليها ، على الأقل في دورك كمختبِر.

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

عدم التوافق بين التبعيات يعطيني كوابيس على وجه الخصوص. حدث كابوس واحد عندما كنت أعمل مع Nightwatch.js لاختبار واجهة المستخدم. يستخدم Nightwatch.js WebDriver ، والذي يعتمد بالطبع على Chrome. عندما انطلق Chrome في التحديث ، كانت هناك مشكلة في التوافق: لم يعد Chrome و WebDriver و Nightwatch.js يعملان معًا ، مما تسبب في فشل تصميماتنا من وقت لآخر.

الحديث عن التبعيات : هناك إشارة مشرفة إلى أي مشكلات npm ، مثل الأذونات المفقودة أو تعطل npm. لقد جربت كل هذه الأشياء في مراقبة CI.

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

3. أسباب جانب المنتج

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

طرق محاربة التقشر

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

ركز على فريقك

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

خلال سنوات عملي في مجال التكنولوجيا ، صادفت أربع استراتيجيات تستخدمها الفرق لمواجهة التقلبات:

  1. لا تفعل شيئًا وتقبل نتيجة الاختبار غير المستقرة.
    بالطبع ، هذه الاستراتيجية ليست حلاً على الإطلاق. لن يسفر الاختبار عن أي قيمة لأنك لا تستطيع الوثوق به بعد الآن - حتى إذا قبلت التقلبات. لذا يمكننا تخطي هذا بسرعة كبيرة.
  2. أعد محاولة الاختبار حتى يتم اجتيازه.
    كانت هذه الإستراتيجية شائعة في بداية مسيرتي المهنية ، مما أدى إلى الاستجابة التي ذكرتها سابقًا. كان هناك بعض القبول بإعادة محاولة الاختبارات حتى اجتيازها. لا تتطلب هذه الإستراتيجية تصحيح الأخطاء ، لكنها كسولة. بالإضافة إلى إخفاء أعراض المشكلة ، سيؤدي ذلك إلى إبطاء مجموعة الاختبار بشكل أكبر ، مما يجعل الحل غير قابل للتطبيق. ومع ذلك ، قد تكون هناك بعض الاستثناءات لهذه القاعدة ، والتي سأشرحها لاحقًا.
  3. احذف ونسيان الاختبار.
    هذا واحد لا يحتاج إلى شرح: ما عليك سوى حذف الاختبار غير المستقر ، بحيث لا يزعج مجموعة الاختبار الخاصة بك بعد الآن. بالتأكيد ، سيوفر لك المال لأنك لن تحتاج إلى تصحيح وإصلاح الاختبار بعد الآن. ولكنه يأتي على حساب فقدان القليل من تغطية الاختبار وفقدان إصلاحات الأخطاء المحتملة. الاختبار موجود لسبب ما! لا تطلق النار على الرسول بحذف الاختبار.
  4. الحجر الصحي والإصلاح.
    لقد حققت أكبر قدر من النجاح مع هذه الاستراتيجية. في هذه الحالة ، نتخطى الاختبار مؤقتًا ، ونطلب من مجموعة الاختبار تذكيرنا باستمرار بأنه تم تخطي الاختبار. للتأكد من عدم التغاضي عن الإصلاح ، سنقوم بجدولة تذكرة للسباق التالي. تعمل تذكيرات الروبوت أيضًا بشكل جيد. بمجرد إصلاح المشكلة التي تسبب التقلبات ، سنقوم بدمج (أي إلغاء تخطي) الاختبار مرة أخرى. لسوء الحظ ، سنفقد التغطية مؤقتًا ، لكنها ستعود مع الإصلاح ، لذلك لن يستغرق ذلك وقتًا طويلاً.
تم تخطي الاختبارات ، مأخوذة من تقرير من CI الخاص بنا
تم تخطي الاختبارات ، مأخوذة من تقرير من CI الخاص بنا. (معاينة كبيرة)

تساعدنا هذه الاستراتيجيات في التعامل مع مشكلات الاختبار على مستوى سير العمل ، ولست الوحيد الذي واجهها. في مقالته ، توصل سام سافرون إلى نتيجة مماثلة. لكن في عملنا اليومي ، يساعدوننا إلى حدٍ ما. لذا ، كيف نواصل العمل عندما تأتي مثل هذه المهمة في طريقنا؟

احتفظ بالاختبارات معزولة

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

المثال أدناه مأخوذ من اختبارات واجهة المستخدم لمنصة التجارة الإلكترونية ، ويتعامل مع تسجيل دخول العميل في واجهة المتجر. (الاختبار مكتوب بلغة JavaScript ، باستخدام إطار عمل Cypress.)

 // File: customer-login.spec.js let customer = {}; beforeEach(() => { // Set application to clean state cy.setInitialState() .then(() => { // Create test data for the test specifically return cy.setFixture('customer'); }) }):

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

زيادة تحسين هيكل الاختبار

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

عندما يتعلق الأمر بعدم افتراض ترتيب البيانات (على سبيل المثال ، عند التعامل مع ترتيب الإدخالات في قائمة في اختبار واجهة المستخدم) ، يمكننا تصميم اختبار ليعمل بشكل مستقل عن أي ترتيب. لإعادة مثال الشبكة التي تحتوي على معلومات بداخلها ، لن نستخدم المحددات الزائفة أو CSS الأخرى التي لها اعتماد قوي على النظام. بدلاً من المحدد nth-child(3) ، يمكننا استخدام نص أو أشياء أخرى لا يهم ترتيبها. على سبيل المثال ، يمكننا استخدام تأكيد مثل ، "اعثر لي على العنصر الذي يحتوي على هذه السلسلة النصية في هذا الجدول".

انتظر! محاولات إعادة الاختبار هل هي جيدة في بعض الأحيان؟

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

المثال التالي هو أحد الأمثلة التي استخدمتها في CI الخاص بنا مع GitLab. قد تحتوي البيئات الأخرى على بنية مختلفة لتحقيق عمليات إعادة المحاولة ، ولكن هذا يجب أن يمنحك طعمًا:

 test: script: rspec retry: max: 2 when: runner_system_failure

في هذا المثال ، نقوم بتكوين عدد المحاولات التي يجب إجراؤها في حالة فشل المهمة. الأمر المثير للاهتمام هو إمكانية إعادة المحاولة إذا كان هناك خطأ في نظام العداء (على سبيل المثال ، فشل إعداد المهمة). نحن نختار إعادة محاولة عملنا فقط في حالة فشل شيء ما في إعداد عامل الإرساء.

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

 { "retries": { // Configure retry attempts for 'cypress run` "runMode": 2, // Configure retry attempts for 'cypress open` "openMode": 2, } }

يمكنك تنشيط عمليات إعادة المحاولة التجريبية في ملف تكوين Cypress ، cypress.json . هناك ، يمكنك تحديد محاولات إعادة المحاولة في عداء الاختبار ووضع مقطوعة الرأس.

استخدام أوقات الانتظار الديناميكية

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

بدلاً من ذلك ، استخدم أوقات الانتظار الديناميكية. هناك العديد من الطرق للقيام بذلك ، ولكن Cypress يتعامل معها بشكل جيد.

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

وقت انتظار ثابت ، موجود في سجل اختبار Cypress
وقت انتظار ثابت ، موجود في سجل اختبار Cypress. (معاينة كبيرة)

يستخدم هذا المثال وقت انتظار صريح للعنصر ذي المحدد .offcanvas . سيستمر الاختبار فقط إذا كان العنصر مرئيًا حتى المهلة المحددة ، والتي يمكنك تهيئتها:

 // Wait for changes in UI (until element is visible) cy.get(#element).should('be.visible');

هناك إمكانية أخرى رائعة في Cypress للانتظار الديناميكي وهي ميزات شبكتها. نعم ، يمكننا انتظار حدوث الطلبات ونتائج ردودهم. أستخدم هذا النوع من الانتظار بشكل خاص في كثير من الأحيان. في المثال أدناه ، نحدد طلب الانتظار ، ونستخدم أمر wait لانتظار الاستجابة ، ونؤكد رمز الحالة الخاص به:

 // File: checkout-info.spec.js // Define request to wait for cy.intercept({ url: '/widgets/customer/info', method: 'GET' }).as('checkoutAvailable'); // Imagine other test steps here... // Assert the response's status code of the request cy.wait('@checkoutAvailable').its('response.statusCode') .should('equal', 200);

بهذه الطريقة ، يمكننا الانتظار تمامًا طالما يحتاج تطبيقنا ، مما يجعل الاختبارات أكثر استقرارًا وأقل عرضة للتقشر بسبب تسرب الموارد أو مشكلات بيئية أخرى.

تصحيح الاختبارات غير المستقرة

نحن نعرف الآن كيفية منع الاختبارات غير المستقرة حسب التصميم. ولكن ماذا لو كنت تتعامل بالفعل مع اختبار غير مستقر؟ كيف يمكنك التخلص منه؟

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

 // Use in build Lodash to repeat the test 100 times Cypress._.times(100, (k) => { it(`typing hello ${k + 1} / 100`, () => { // Write your test steps in here }) })

يعد الحصول على مزيد من المعلومات حول هذا الاختبار غير المستقر أمرًا صعبًا بشكل خاص في CI. للحصول على المساعدة ، راجع ما إذا كان إطار الاختبار الخاص بك قادرًا على الحصول على مزيد من المعلومات حول جهازك. عندما يتعلق الأمر باختبار الواجهة الأمامية ، يمكنك عادةً استخدام console.log في اختباراتك:

 it('should be a Vue.JS component', () => { // Mock component by a method defined before const wrapper = createWrapper(); // Print out the component's html console.log(wrapper.html()); expect(wrapper.isVueInstance()).toBe(true); })

هذا المثال مأخوذ من اختبار Jest للوحدة الذي أستخدم فيه console.log للحصول على ناتج HTML للمكون الذي يتم اختباره. إذا كنت تستخدم إمكانية التسجيل هذه في عداء اختبار Cypress ، فيمكنك حتى فحص الإخراج في أدوات المطور التي تختارها. بالإضافة إلى ذلك ، عندما يتعلق الأمر بـ Cypress in CI ، يمكنك فحص هذا الإخراج في سجل CI الخاص بك باستخدام مكون إضافي.

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

حارب كوابيس التقشر!

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

اكتشاف الأعلام الحمراء

إن منع الاختبارات غير المستقرة في المقام الأول هو الأفضل بالطبع. للتلخيص السريع ، إليك بعض العلامات الحمراء:

  • الاختبار كبير ويحتوي على الكثير من المنطق.
  • يغطي الاختبار الكثير من التعليمات البرمجية (على سبيل المثال ، في اختبارات واجهة المستخدم).
  • يستفيد الاختبار من أوقات الانتظار الثابتة.
  • يعتمد الاختبار على الاختبارات السابقة.
  • يؤكد الاختبار البيانات التي لا يمكن التنبؤ بها بنسبة 100٪ ، مثل استخدام المعرفات أو الأوقات أو البيانات التوضيحية ، خاصة تلك التي يتم إنشاؤها عشوائيًا.

إذا احتفظت بالمؤشرات والاستراتيجيات الواردة في هذه المقالة في الاعتبار ، فيمكنك منع الاختبارات غير المستقرة قبل حدوثها. وإذا جاءوا ، فستعرف كيفية تصحيحها وإصلاحها.

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

آمل أن أكون قادرًا على تخفيف بعض آلامك ومخاوفك على الأقل من التقشر!

قراءة متعمقة

إذا كنت تريد معرفة المزيد حول هذا الموضوع ، فإليك بعض الموارد والمقالات الأنيقة التي ساعدتني كثيرًا:

  • مقالات حول "تقشر ،" Cypress.io
  • "إعادة محاولة الاختبارات الخاصة بك في الواقع أمر جيد (إذا كان النهج الذي تتبعه صحيحًا) ،" Filip Hric ، Cypress.io
  • "اختبار التقلب: طرق تحديد الاختبارات غير المستقرة والتعامل معها" ، جايسون بالمر ، Spotify R&D Engineering
  • "الاختبارات غير المستقرة في Google وكيفية التخفيف منها" ، John Micco ، مدونة Google الاختبارية