توسيع نطاق اختبار Android على Odnoklassniki



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

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

القليل من التاريخ


تم كتابة أول الاختبارات الذاتية في Odnoklassniki في Selenium ، لإطلاقها رفعوا Jenkins و Selenium Grid مع Selenium Hub ومجموعة من عقدة Selenium.

حل سريع ، بداية سريعة ، ربح سريع - مثالي.

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

في ذلك الوقت ، بدت البنية التحتية للاختبار الآلي كما يلي:



ومع ذلك ، مع وجود كمية من عقدة السيلينيوم أكبر من أو تساوي 200 ، لم يتمكن المحور من التعامل مع الحمل. الآن تمت دراسة هذه المشكلة بالفعل ، ولهذا السبب ظهرت أدوات مثل Zalenium أو Selenoid المفضلة لدى الجميع. ولكن في عام 2014 لم يكن هناك حل قياسي ، لذلك قررنا أن نصنع الحل الخاص بنا.

تحديد الحد الأدنى من المتطلبات التي يجب أن تلبيها الخدمة:

  1. قابلية التوسع. لا نريد الاعتماد على قيود Selenium Hub.
  2. المزيد. في عام 2014 ، لم يكن Selenium Hub مشهورًا بالعمل المستقر.
  3. التسامح مع الخطأ. نحن بحاجة إلى القدرة على مواصلة عملية الاختبار في حالة فشل مركز البيانات أو أي من الخوادم.

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

منسق




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

ميزة المنسق هي أنه يدمج جميع مديري العقدة في المزارع.

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



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

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



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

مدير العقدة


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



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

التفاعل


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

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



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

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

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

ذكري المظهر


عندما يتعلق الأمر بالاختبار على Android ، هناك عادةً طريقتان رئيسيتان. الأول هو استخدام WebDriver - هذه هي طريقة عمل Selendroid و Appium. والثاني - في العمل مع الأدوات الأصلية ، وبالتالي نفذت Robotium أو UI Automator أو Espresso.

أوجه التشابه الأساسية بين هذه الأساليب هي الحصول على الجهاز والحصول على المتصفح.

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

في عام 2015 ، بدأ Odnoklassniki في تغطية تطبيق Android الخاص به باستخدام الاختبارات الذاتية. اخترنا جهاز Linux واحدًا ، وقمنا بتوصيل جهاز حقيقي واحد عبر USB وبدأنا في كتابة الاختبارات على Robotium. يتيح لك هذا الحل البسيط الحصول على نتائج بسرعة.

مر الوقت ، ازداد عدد الاختبارات وعدد الأجهزة. لحل مهام الإدارة ، تم إنشاء Device Manager - وهو مجمّع فوق أوامر adb (Android Debug Bridge) ، والذي يسمح لواجهة http api بتنفيذها.

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



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

المزرعة جاهزة - يمكنك توصيل الهواتف.



كثيرون على دراية بهذه الصورة. سمعت أنه إذا كنت تعمل في مزارع Android ، فأنت كما لو كنت في الجحيم كل يوم.



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

ما هو المطلوب لتشغيل محاكي Android؟

أولاً ، تحتاج إلى Android SDK مع مجموعة من الأدوات المساعدة.

ثم تحتاج إلى إنشاء AVD - جهاز Android الظاهري - هذه هي الطريقة التي سيتم بها تنظيم محاكي Android الخاص بك - ما هي الهندسة التي ستحتوي عليها ، وعدد النوى التي ستستخدمها ، وما إذا كانت خدمات Google ستكون متاحة ، وما إلى ذلك.



بعد ذلك ، تحتاج إلى تحديد اسم AVD الذي تم إنشاؤه ، وتعيين المعلمات ، على سبيل المثال ، نقل المنفذ الذي سيتم تشغيل ADB عليه ، والبدء.

ومع ذلك ، هناك خصوصية في مثل هذا المخطط - يسمح لك النظام بتشغيل محاكي مثيل واحد فقط على AVD واحد محدد.

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

أداء


بناءً على نتائج العمل مع AVD ، قمنا بتطوير العديد من التوصيات الداخلية:

  1. 86 , ARM . dev/kvm Linux HAXM- Mac Windows
  2. GPU- . , . , , , Android-
  3. .
  4. , localhost,

أما بالنسبة إلى Docker-images للاختبار على Android ، فأريد تسليط الضوء على Agoda و Selenoid ، فهم يستخدمون إمكانيات محاكيات Android إلى أقصى حد.

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

في نهاية عام 2018 ، تم إنشاء CloudNode-Manager ، ويتصل بالمنسق ، ويتلقى المهام ويتم تشغيله باستخدام الأوامر في السحابة. بدلاً من آلات الحديد ، تستخدم هذه الخدمة موارد السحابة الواحدة - السحابة الخاصة Odnoklassniki.

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

هذا ما يحدث إذا حاولت تشغيل تثبيت ADB على 250 محاكيًا من جهاز واحد.



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

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



ولكن ليس كل شيء وردية للغاية. ربما لاحظت أنه لم يتم حتى الآن قول أي شيء عن جودة الاختبارات.



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

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

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

تبدو الاختبارات الآن على النحو التالي:



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

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

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

يحتوي QueueRunner على تدفق اختبار - فهو يراقب دورة حياة الاختبار. يتكون التدفق الافتراضي الذي نستخدمه الآن من خمس خطوات:

  1. جهاز استقبال. عند هذه النقطة ، يطلب Devicemanager من خلال المنسق جهازًا حقيقيًا أو افتراضيًا.
  2. . APK , – , .
  3. ,

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



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

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

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

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

عمليات التطوير


دعونا نرى كيف ترتبط البنية التحتية للاختبار بعملية التطوير وكيف يراها المختبرون والمطورون.

يستخدم فريق Android لدينا GitFlow القياسي:



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

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



إعداد التقارير


هذه هي الطريقة التي تبدو بها تقارير Stash:



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

هذه هي الطريقة التي تبدو بها المقارنة بين الإطلاقين:



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

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

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

ملخص


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

بدا وكأنه وقت تشغيل الاختبار لمدة أسبوع واحد في عام 2016 - من خمسين دقيقة أو أكثر.



هذه هي الطريقة التي تبدو بها الآن:



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

All Articles