
مساء الخير أيها القراء الأعزاء. اسمي فيكتور بوروف. أعمل كمطور في ISPsystem وأريد مشاركة تجربتي في أتمتة الاختبار.
حدث أن الاختبار اليدوي ساد في بلدنا ، وقضى المختبرون الكثير من الوقت في تنفيذ نفس الإجراءات. بمجرد أن فكرنا: لماذا لا نعلم اللجنة لتكرار إجراءات المختبر ، لأنها في الواقع تتحول جميعها إلى مكالمات API محددة. سيسمح هذا للأشخاص بكتابة الاختبارات حتى بدون مهارات البرمجة.
قررنا كتابة وحدة لإنشاء اختبارات تلقائية. حتى يتمكن المختبر من الضغط على الزر لإنشاء اختبار ، واستيفاء شروط حالة الاختبار ، في النهاية ، انقر فوق "إنهاء" - وهذا كل شيء ، كان الاختبار جاهزًا! فكرة بسيطة ، ولكن إدراك أنها لم تكن سهلة. لأننا أردنا أن يتم تكييف هذه الوحدة إلى أقصى حد لمنتجاتنا والاستفادة من واجهة موحدة: بحيث يبدو الفيديو المسجل كحالة اختبار جاهزة. سيؤدي ذلك إلى القضاء تمامًا على العمل اليدوي لكتابة الاختبارات. كان النظام الناتج يسمى "مسجل الشريط".
واجهة لعرض ظروف حالة الاختبارمبدأ العمل
تتم كتابة جميع معلمات الطلب (رؤوس HTTP ، ومتغيرات البيئة ، وبيانات POST ، إن وجدت) والاستجابة بأكملها إلى ملف xml. يتم تعيين رقم تسلسلي لكل سجل. تنقسم جميع الطلبات إلى تعديل وغير تعديل. بعد تسجيل الاختبار ، يتم قطع العديد من الاستعلامات غير المعدلة ، لأنها لا تؤثر على تنفيذ الاختبارات وتؤخر عملية التنفيذ وتربكها فقط (وبالتالي أرقام التسلسل المفقودة في لقطة الشاشة).
أثناء التسجيل ، يتيح لك مسجل الأشرطة ضبط التحقق من القيم في الحقول الموجودة في النماذج وفي أعمدة القوائم بنقرة واحدة. كما يسمح لك بتسجيل الاختبارات السلبية ، وتذكر الخطأ الذي أعادته اللوحة أثناء تسجيل الاختبار.
أثناء التشغيل ، يتم إرسال الطلبات مباشرة إلى واجهة برمجة التطبيقات للتطبيق دون استخدام متصفح.
في الواقع ، مسجل الشريط هو وحدة متكاملة في جميع منتجاتنا ويسمح لك بتثبيت معالجات تستجيب للأحداث. مكتوب باستخدام COREmanager.
مثال على تسجيل مكالمة واحدة بواسطة مسجل شرائط:
سجل<params> <param name="CONTENT_LENGTH">210</param> <param name="CONTENT_TYPE">application%2Fx%2Dwww%2Dform%2Durlencoded%3B%20charset%3DUTF%2D8</param> <param name="HTTPS">on</param> <param name="HTTP_ACCEPT">text%2Fhtml%2C%20%2A%2F%2A%3B%20q%3D0%2E01</param> <param name="HTTP_ACCEPT_LANGUAGE">en%2DUS%2Cen%3Bq%3D0%2E5</param> <param name="HTTP_CACHE_CONTROL">no%2Dcache</param> <param name="HTTP_CONNECTION">keep%2Dalive</param> <param name="HTTP_COOKIE">corelang5%3Dorion%3Aru%3B%20ispmgrlang5%3Dorion%3Aru%3B%20ipmgrlang5%3Dorion%3Aru%3B%20ipmgrses5%3Dbdd69179d627%3B%20ispmgrses5%3D14157f7bbc5e%3B%20menupane%3D30%5Faccount%2D1%253A30%5Fdomains%2D1%253A30%5Fwebserver%2D1%253A30%5Fantispam%2D1%253A30%5Fmaintain%2D1%253A30%5Ftool%2D1%253A30%5Fstat%2D1%253A30%5Fsrvset%2D1%253A30%5Fsysstat%2D1%253A30%5Fintegration%2D1%253A30%5Fset%2D1%253A30%5Fmgrhelp%2D1</param> <param name="HTTP_HOST">172%2E31%2E240%2E175%3A1500</param> <param name="HTTP_ISP_CLIENT">Web%2Dinterface</param> <param name="HTTP_PRAGMA">no%2Dcache</param> <param name="HTTP_REFERER">https%3A%2F%2F172%2E31%2E240%2E175%3A1500%2Fispmgr</param> <param name="HTTP_USER_AGENT">Mozilla%2F5%2E0%20%28X11%3B%20Ubuntu%3B%20Linux%20x86%5F64%3B%20rv%3A24%2E0%29%20Gecko%2F20100101%20Firefox%2F24%2E0</param> <param name="HTTP_X_REQUESTED_WITH">XMLHttpRequest</param> <param name="QUERY_STRING"/> <param name="REMOTE_ADDR"></param> <param name="REMOTE_PORT">38640</param> <param name="REQUEST_METHOD">POST</param> <param name="REQUEST_URI">%2Fispmgr</param> <param name="SCRIPT_NAME">%2Fispmgr</param> <param name="SERVER_ADDR">172%2E31%2E240%2E175</param> <param name="SERVER_NAME">172%2E31%2E240%2E175</param> <param name="SERVER_PORT">1500</param> </params> <postdata>func%3Demaildomain%2Eedit%26elid%3D%26name%3Dtest%2Eemail%26owner%3Dusr%26ipsrc%3Dauto%26defaction%3Derror%26redirval%3D%26spamassassin%3Doff%26avcheck%3Doff%26clicked%5Fbutton%3Dok%26progressid%3Dfalse%5F1424243906672%26sok%3Dok%26sfrom%3Dajax%26operafake%3D1424243906673</postdata> <answer> <doc lang="ru" func="emaildomain.edit" binary="/ispmgr" host="https://172.31.240.175:1500" features="cba82687e7756e2c0195c88d4180f5d50" notify="0" theme="/manimg/orion/" css="main.css" logo="logo-ispmgr.png" logolink="" favicon="favicon-ispmgr.ico" localdir="default/"> <metadata name="emaildomain.edit" type="form" mgr="ispmgr" decorated="yes"> <form> <field name="name"> <input type="text" name="name" required="yes" check="domain" convert="punycode" maxlength="255"/> </field> // <buttons> <button name="ok" type="ok"/> <button name="cancel" type="cancel"/> </buttons> </form> </metadata> <messages name="emaildomain.edit" checked="cba82687e7756e2c0195c88d4180f5d5"> <msg name="currentmonth"> </msg> // </messages> <doc lang="ru" func="emaildomain.edit" binary="/ispmgr" host="https://172.31.240.175:1500" features="cba82687e7756e2c0195c88d4180f5d50" notify="0" theme="/manimg/orion/" css="main.css" logo="logo-ispmgr.png" logolink="" favicon="favicon-ispmgr.ico" localdir="default/"> <slist name="owner"> <val key="usr">usr</val> </slist> <slist name="defaction"> <val msg="yes" key="error"> </val> </slist> <slist name="ipsrc"> <val msg="yes" key="auto"> </val> </slist> <name/> <avcheck>off</avcheck> <owner>usr</owner> <ipsrc>auto</ipsrc> </doc> <id>test.email</id> <ok/> <tparams> <clicked_button>ok</clicked_button> </tparams> </doc> </answer> <localmacro> <macros name="mpre_HostIP" field="ipsrc">auto</macros> </localmacro>
التحسينات (التي لم نفكر فيها مسبقًا)
الانتظار
يمكن لأي شخص "مجرد الانتظار" ، كمبيوتر - لا. كانت كتابة المشاكل هي واحدة من أولى المشاكل التي كان من المفترض أن يحلها مسجل الشريط. ما لم يخترعه الناس من أجل الانتظار لإتمام العملية. تم تنفيذ توقع مهام الخلفية والقدرة على إضافة نقطة توقف في الخطوة المحددة لعدد محدد من الثواني.
تسجيل وتحرير خطوات الاختبار
ربما يتذكر الجميع أوقات الآلات الكاتبة: خطأ واحد - ويجب عليك إعادة طباعة الصفحة بأكملها.

حتى لا يضطر المختبر إلى إعادة كتابة الاختبار بالكامل بإجراء خاطئ ، تمت إضافة آلية لإعادة تسجيل الاختبار من أي خطوة بعد الحفظ. تكون القدرة على التحرير مفيدة عندما تحتاج إلى تكييف الاختبار مع التغييرات في سلوك الوظائف المختبرة.
وحدات الماكرو للمتغيرات
أثناء الاختبارات ، تغيرت القيم في المعلمات المرسلة والمدققة اعتمادًا على الخادم الذي كانت تعمل عليه. مثال على هذه البيانات هو عناوين IP. من المستحيل التعرف عليهم في مرحلة تسجيل الاختبار ، لذلك أضفت نظامًا ماكرو. هذا سمح لنا بإنشاء اختبارات غير مرتبطة بشكل صارم بالبيئة. عيب الحل هو أنه بعد التسجيل ، يجب تحديد وحدات الماكرو يدويًا.
هناك مشكلة أخرى تؤدي إلى تعقيد العمل مع مسجل الأشرطة بشكل كبير وهي استخدام المفاتيح غير الأصلية. لم نلاحظ ذلك على الفور ، حيث قمنا باختبار مسجل الشريط على ISPmanager ، والذي يستخدم معرفات أصلية. ولكن في بعض اللوحات الأخرى ، يتم تحديد السجل بمعرف فريد. لذلك ، كان علي تعليم مسجل الشريط ليس فقط للحصول على المعرّف بعد إنشاء السجل أو الكائن (حيث يمكن أن يتغير المعرف من البداية إلى البداية) ، ولكن أيضًا لاستبداله في جميع الطلبات اللاحقة.
دعم تنسيق JUnit
يتم تشغيل الاختبارات الناتجة عن الأشرطة تلقائيًا في بيئة التكامل المستمر لجينكينز. بعد اكتمال الاختبارات ، يتم إنشاء ملف xml يحتوي على البيانات بتنسيق JUnit. من أجل تشكيل الملف بشكل صحيح ، تم إدخال قيود على تسمية الاختبارات. على سبيل المثال ، وقع اختبار User.Create.xml في testuite مع اسم المستخدم ، وبالتالي ، كان يحتوي على testcase يسمى إنشاء. في حالة حدوث خطأ ، تمت إضافة عقدة فشل مع وصف كامل للخطأ إليها.
المقاييس
يتم حساب عدد الوظائف الفريدة المسماة أثناء اجتياز الاختبارات ويتم تحديد النسبة كنسبة مئوية من إجمالي عدد الوظائف ، باستثناء تلك المتاحة للاستخدام الداخلي فقط. وبالتالي ، يتم قياس أبسط تغطية اختبار. بالإضافة إلى ذلك ، توضح المقاييس إجمالي الوقت المستغرق لإكمال الاختبار وعدد الاختبارات الناجحة والفاشلة.
مستودع الاختبار
يحل مستودع الاختبار أولاً مشكلة نقل الاختبارات الجاهزة إلى خوادم أخرى. كما أنه مفيد عندما يكتب العديد من المختبرين الاختبارات. تم تطوير لوحة صغيرة لتخزين اختبارات التخزين ونشرها أيضًا على أساس COREmanager. يحتوي مسجل الشريط على وحدة لمزامنة الاختبارات مع التخزين. عند كتابة اختبار جديد أو تفريغ اختبارات من المستودع ، تصبح تلقائيًا غير متاحة للتحميل في المستودع بحيث لا يكون هناك أي لبس. بعد تغيير الاختبار ، يتم زيادة رقم المراجعة بحيث يتم تحميل الاختبارات فقط بعد التغييرات في المستودع.
الصعوبات (حسنا ، بدونها)
أظهر استخدام مسجل الشريط أن جميع وظائف واجهة برمجة التطبيقات لم تتبع توصياتنا الداخلية. على وجه الخصوص ، لم ترجع جميع الوظائف معرف السجل بعد إنشائه. اضطررت للعودة ، بما في ذلك إلى رمز العمل ، وجعله يتماشى مع المتطلبات.
الجمود مشكلة أخرى. تتضمن اللوحة أداء بعض الإجراءات المهمة في الوضع الحصري. ومسجل الشريط ، كونه جزءًا من نفس اللوحة ، مما تسبب في مثل هذه الوظائف ، تسبب في تجمد النظام بأكمله. كان من الممكن تحديد ذلك فقط بمساعدة GDB (لم يتذكر أحد هذه الميزة). لسوء الحظ ، كانت هناك عكازات ، لأنه تقرر عند تشغيل اختبارات مسجل الشريط لأداء هذه الوظائف في وضع متعدد الخيوط. من الناحية النظرية ، كان من الممكن تصميم مسجل شريط ليس بوحدة نمطية ، ولكن بلوحة منفصلة. لكننا لم نحاول.
للأسف ، فشلت الكتابة والنسيان أيضًا. تتغير واجهة منتجاتنا وتصبح أكثر تعقيدًا. علاوة على ذلك ، ينمو عدد مكونات الواجهة بنشاط. لذلك ، يجب تعديل مسجل الشريط من وقت لآخر ، بحيث عندما تظهر مكونات جديدة ، يمكنه تحليل هيكلها ومعالجة نتائج الاستعلامات.
الخلاصة
ساعد إنشاء جهاز تسجيل على تحسين جودة المنتجات التي تم اختبارها. توفير الوقت والموارد لتدريب المختبرين. على طول الطريق ، سمح لنا مسجل الأشرطة بمراجعة واجهة برمجة التطبيقات الخاصة بنا للامتثال للتوصيات الداخلية ، وبالتالي ، جعل واجهة برمجة التطبيقات أكثر منطقية.