تطوير تطبيق جوال بدون خادم

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

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

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



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

اقترحت كتابة خلفية moch (قبل أن أصبح مطورًا لنظام iOS ، لعبت مع .NET في أحادي). كانت فكرة التنفيذ بسيطة: وفقًا لمواصفات معينة ، كان من الضروري كتابة طرق كعب الروتين التي ستأخذ البيانات من ملفات JSON المعدة مسبقًا. لقد قرروا ذلك.

بعد أسبوعين ، ذهبت في إجازة وفكرت: "لماذا لا أقوم تلقائيًا بإنشاء كل هذا؟" لذا ، لمدة أسبوعين من الإجازة ، كتبت ما يشبه المترجم الشفهي الذي يأخذ مواصفات APIBlueprint ويقوم بإنشاء .NET Web App منه (رمز C #).

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

الآن ، بعد عدة سنوات ، أخذت في الاعتبار الأخطاء التي ارتكبتها (وكان هناك الكثير منها) وأعدت كتابة الصك بالكامل.

أغتنم هذه الفرصة - شكرًا جزيلاً للزملاء الذين ساعدوا بتعليقاتهم ونصائحهم. وكذلك للقادة الذين تحملوا كل ما عندي من "التعسف الهندسي".

مقدمة


كقاعدة عامة ، يبدو أي تطبيق خادم - عميل مثل هذا:



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



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

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



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

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

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

لذلك ، هناك المشاكل التالية:

  1. الخادم مفقود تماما. لهذا السبب ، من المستحيل التصميم والاختبار والحاضر.
  2. ليس لدى الخادم وقت ، والذي يتداخل مع التطوير وقد يتداخل مع الاختبار.
  3. نريد اختبار الحالات الحدودية ، ولا يمكن للخادم السماح بذلك دون إيماءات طويلة.
  4. تؤثر على اختبار العروض التقديمية وتهديدها.
  5. تعطل الخادم (مرة واحدة ، أثناء التطوير المستقر ، فقدنا الخادم لمدة 3.5 أيام).

لمكافحة هذه المشاكل ، تم إنشاء Mocker.

مبدأ العمل


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

التسلسل كما يلي:

1. يرسل العميل طلب.
2. السخرية يتلقى الطلب.
3. السخرية يجد السخرية المطلوبة.
4. يسترجع السخرية السخرية المرغوبة.

إذا كان كل شيء واضحًا بالنقطتين 1 و 2 و 4 ، فإن 3 تثير أسئلة.

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

Mock هو ملف JSON بالتنسيق التالي:

{ "url": "string", "method": "string", "statusCode": "number", "response": "object", "request": "object" } 

دعنا نحلل كل حقل على حدة.

رابط


يتم استخدام هذه المعلمة لتحديد عنوان URL للطلب الذي يصل إليه العميل.

على سبيل المثال ، إذا قدم أحد تطبيقات الهاتف المحمول طلبًا إلى url host.dom/path/to/endpoint ، فعندئذٍ في حقل url نحتاج إلى الكتابة /path/to/endpoint .
بمعنى ، هذا الحقل يخزن المسار النسبي إلى نقطة النهاية .

يجب تنسيق هذا الحقل بتنسيق url-template ، أي أن التنسيقات التالية مسموح بها:

  1. /path/to/endpoint - عنوان url العادي. عند تلقي الطلب ، ستقوم الخدمة بمقارنة حرف الأسطر بحرف.
  2. /path/to/endpoint/{number} - عنوان url بنمط المسار. سوف يستجيب النموذج الذي يحمل عنوان URL هذا لأي طلب يطابق هذا النمط.
  3. /path/to/endpoint/data?param={value} - عنوان url بنمط المعلمة. سوف يستهزأ باستخدام عنوان url هذا بطلب يحتوي على المعلمات المحددة. علاوة على ذلك ، إذا كانت إحدى المعلمات غير موجودة في الطلب ، فلن تتطابق مع القالب.

وبالتالي ، من خلال التحكم في معلمات URL ، يمكنك تحديد أن نموذجًا معينًا سيعود إلى عنوان url محدد.

طريقة


هذه هي طريقة http المتوقعة. على سبيل المثال POST أو GET .
يجب أن تحتوي السلسلة على أحرف كبيرة فقط.

statusCode


هذا هو رمز حالة http للاستجابة. وهذا هو ، من خلال طلب هذا وهمية ، سوف يتلقى العميل استجابة مع الحالة المسجلة في حقل statusCode.

استجابة


يحتوي هذا الحقل على كائن JSON الذي سيتم إرساله إلى العميل في نص الاستجابة لطلبه.

طلب


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

 { "url": "/auth", "method": "POST", "statusCode": 200, "response": { "token": "cbshbg52rebfzdghj123dsfsfasd" }, "request": { "login": "Tester", "password": "Valid" } } 

 { "url": "/auth", "method": "POST", "statusCode": 400, "response": { "message": "Bad credentials" }, "request": { "login": "Tester", "password": "Invalid" } } 

إذا أرسل العميل طلبًا مع الهيئة:

 { "login": "Tester", "password": "Valid" } 

ثم ردا سيتلقى:

 { "token": "cbshbg52rebfzdghj123dsfsfasd" } 

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

 { "login": "Tester", "password": "Invalid" } 

ثم ردا سيتلقى:
 { "message": "Bad credentials" } 

ويمكننا التحقق من القضية بكلمة مرور خاطئة. وهكذا لجميع الحالات الأخرى.

والآن سنكتشف كيف يعمل التجميع والبحث عن الموك المطلوب.



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

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

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

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

 { "url": "/products", "method": "GET", "statusCode": 200, "response": { "name": "product", "currency": 1, "value": 20 } } 

 { "url": "/products", "method": "GET", "statusCode": 200, "response": { "name": "gdshfjshhkfhsdgfhshdjgfhjkshdjkfsfgbjsfgskdf", "currency": 5, "value": 100000000000 } } 

 { "url": "/products", "method": "GET", "statusCode": 200, "response": null } 

 { "url": "/products", "method": "GET", "statusCode": 400, "response": null } 

ثم ، عندما نسمي طريقة GET / products لأول مرة ، سنحصل أولاً على الإجابة:

 { "name": "product", "currency": 1, "value": 20 } 

عندما نسميها للمرة الثانية ، سوف يتحول مؤشر التكرار إلى العنصر التالي ويعود إلينا:

 { "name": "gdshfjshhkfhsdgfhshdjgfhjkshdjkfsfgbjsfgskdf", "currency": 5, "value": 100000000000 } 

ويمكننا التحقق من سلوك التطبيق إذا حصلنا على بعض القيم الكبيرة. و هكذا.

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

وكيل التخزين المؤقت


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

بعد تلقي الاستجابة بالكود 200 ، يحفظ Mocker الإجابة على ملف Mock (نعم ، يمكنك بعد ذلك نسخها أو تغييرها) ويعود إلى العميل ما حصل عليه من الخادم الحقيقي. علاوة على ذلك ، لا يقوم فقط بحفظ الملف في مكان عشوائي ، ولكنه ينظم الملفات بحيث يمكنك العمل معهم يدويًا ، على سبيل المثال ، يرسل Mocker طلبًا إلى عنوان URL التالي: hostname.dom/main/products/loans/info . بعد ذلك ، سينشئ مجلد hostname.dom ، ثم بداخله سينشئ مجلدًا main ، بداخله مجلد products ...

من أجل تجنب تكرار السخرية ، يتم تكوين الاسم على أساس طريقة http (GET ، PUT ...) وتجزئة من نص الاستجابة للخادم الحقيقي . في هذه الحالة ، إذا كان هناك بالفعل صورة وهمية عن إجابة محددة ، فسيتم استبدالها ببساطة.

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

 X-Mocker-Redirect-Is-On: "true", X-Mocker-Redirect-Host: "hostaname.ex:1234", X-Mocker-Redirect-Scheme: "http" 

إشارة صريحة من الطريق إلى السخرية


في بعض الأحيان تريد من Mocker أن يرجع فقط تلك الموكاتا التي نريدها ، وليس كل ما هو موجود في المشروع.

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

الآن هذا ممكن. لتمكين هذه الوظيفة ، تحتاج إلى استخدام رأس خاص:

 X-Mocker-Specific-Path: path 

على سبيل المثال ، دع Mocker لديه بنية مجلد في الجذر

 root/ block_card_test_case/ mocks.... main_test_case/ blocked_test_case/ mocks... 

إذا كنت بحاجة إلى تشغيل حالة اختبار حول البطاقات المحظورة ، إذن
X-Mocker-Specific-Path: block_card_test_case
إذا كنت بحاجة إلى تشغيل حالة اختبار مرتبطة بإغلاق الشاشة الرئيسية ، إذن
X-Mocker-Specific-Path: main_test_case/blocked_test_case

السطح البيني


في البداية ، عملنا مع mokas مباشرة عبر ssh ، ولكن مع زيادة عدد mokas والمستخدمين ، تحولنا إلى خيار أكثر ملاءمة. الآن نحن نستخدم CloudCommander.
في مثال إنشاء عامل الميناء ، يرتبط بحاوية Mocker.

يبدو شيء مثل هذا:



حسنًا ، المكافأة هي محرر ويب ، والذي يسمح لك بإضافة / تغيير moki مباشرةً من المتصفح.



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

نشر


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

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

 git clone https://github.com/LastSprint/mocker.git cd mocker go build . 

فأنت بحاجة إلى كتابة ملف التكوين ( مثال ) وبدء الخدمة:

 mocker config.json 

المشكلات المعروفة


  • بعد كل ملف جديد ، يلزمك curl mockerhost.dom/update_models حتى تتمكن الخدمة من قراءة الملفات مرة أخرى. لم أجد طريقة سريعة وأنيقة لتحديثه بطريقة أخرى
  • في بعض الأحيان ، يُحدث خطأ في CloudCommander (أو قمت بعمل خطأ) ولا يسمح بتحرير moki الذي تم إنشاؤه من خلال واجهة الويب. يتم التعامل معها عن طريق مسح ذاكرة التخزين المؤقت للمتصفح.
  • تعمل الخدمة فقط مع application/json . تدعم الخطط form-url-encoding .

يؤدي


Mocker هي خدمة ويب تعمل على حل مشكلات تطوير تطبيقات خادم العميل عندما يكون الخادم غير جاهز لسبب ما.

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

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

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

مستودع جيثب .

Source: https://habr.com/ru/post/ar477506/


All Articles