اختبار غامض لواجهة الويب. نسخة من التقرير





في بداية هذا العام ، عقدت Tenzor لقاءًا في مدينة إيفانوفو ، حيث قدمت عرضًا تقديميًا حول تجارب الاختبار الغامض للواجهة. هنا نسخة من هذا التقرير.



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



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







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







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







في فيلم "The Matrix" في أحد المشاهد ، يعرض Morpheus على Neo اختيار حبة حمراء أو زرقاء. عمل توماس أندرسون كمبرمج ونتذكر أي خيار اتخذه. إذا كان أحد المختبرين سيئ السمعة ، لكان قد التهم كلا الجهازين ليرى كيف سيتصرف النظام في ظروف غير قياسية.



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



ومع ذلك ، عند إنشاء الاختبارات التلقائية والحفاظ عليها ، فجأة لا يوجد الكثير من العمل التلقائي والكثير من العمل اليدوي:



  1. أنت بحاجة لمعرفة ماذا وكيف تختبر.
  2. تحتاج إلى العثور على العناصر الموجودة على الصفحة ، ودفع محددات المواقع الضرورية إلى كائنات الصفحة.
  3. اكتب وصحح الكود.
  4. — . / , , ROI .






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







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







لنفترض أننا صنعنا مثل هذا TODO ونريد التحقق منه. نحن نأخذ خدمة أو أداة مناسبة ونرى القرود وهي تعمل:







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







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







عكس هذا النهج هو الأساليب الرسمية.







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



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







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







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



غالبًا ما يُنظر إلى اختبار التشويش في سياق اختبار الأمان. ومخطط نموذجي يوضح هذا النهج ، نأخذ من دليل OWASP :







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







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







يقوم المستخدم بإدخال تاريخ جديد والنقر فوق الزر "حفظ". يتم إرسال طلب إلى الخادم ببيانات بتنسيق json.







وإذا كان كل شيء على ما يرام ، فإن الخدمة تستجيب برمز مائتي.







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







وفي حالة الرد ، بدلاً من إرسال رسالة حول تاريخ غير صالح ، تلقينا استثناءً ، فسنصلح الخطأ.



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



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







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







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



إذا أدخلنا بعض النص في حقل النص واضغطنا على Enter ، فستنتقل صفحتنا من حالة إلى أخرى:







تخطيطيًا يمكن تصويرها على النحو التالي:







من هذه الحالة يمكننا الانتقال إلى الثالثة عن طريق إضافة مهمة أخرى إلى القائمة:







ويمكننا حذف المهمة ، والعودة إلى الحالة الأولى:







أو انقر فوق تسمية TODOs والبقاء في الحالة الثانية:







والآن دعونا نحاول تنفيذ إثبات المفهوم لهذا النهج.







للعمل مع المتصفح ، سنأخذ chromedriver ، وسنعمل مع مخطط الحالة والانتقالات من خلال مكتبة NetworkX python ، وسنرسم من خلال yEd.







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







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







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







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

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



دعنا نعود إلى تطبيقنا. الحالة الأولية هي كما يلي:







بعد عشرة تكرارات للتطبيق ، سوف نحصل على الرسم التخطيطي التالي للحالات والانتقالات:







بعد 22 تكرارًا ، هذا ما يلي:







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







إذن ، مع تطبيق تجريبي بسيط لقد فعلناها. وماذا يحدث إذا قمت بتعيين هذا البرنامج النصي على تطبيق ويب حقيقي. وستكون هناك فوضى:







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

خذ للاختبارصفحة مصادقة VLSI:







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











ممتاز! يمكننا الآن اجتياز جميع حالات التطبيق. ومن الناحية النظرية البحتة ، تجد كل الأخطاء التي تعتمد على الأفعال. ولكن كيف تدرس برنامجًا لفهم أن هناك خطأ أمامه؟



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







لنفكر في النمط الأخير "كان مختلفًا من قبل". تشارك الاختبارات التلقائية في اختبار الانحدار.



دعنا نعود إلى الرسم البياني بعد 10 تكرارات من TODO:







دعنا نكسر الكود المسؤول عن فتح عربة التسوق ونجري 10 تكرارات مرة أخرى:







ثم نقارن الرسمين البيانيين ونجد الفرق في الحالات:







يمكننا تلخيص هذا النهج:







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

يمكن العثور على جميع التعليمات البرمجية المصدر وقائمة المواد المستخدمة في المستودع: https://github.com/svdokuchaev/venom . بالنسبة لأولئك الذين يرغبون في فهم استخدام التشويش في الاختبار ، أوصي بشدة بـ The Fuzzing Book . هناك ، في أحد الأجزاء ، يتم وصف نفس النهج لإبهام نماذج HTML البسيطة.






All Articles