كيف يمكن لـ Kotlin المساعدة في اختبار API: حالة Rusfinance Bank





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



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



تحت الخفض ، سنخبرك عن نتائج تجاربنا ، التي نقلناها بكل سرور إلى الإنتاج.



بدون وجه



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



  • تسمح لك ببدء الاختبار بالفعل في مرحلة تطوير الخدمات ؛
  • تبسيط توطين الخطأ ؛
  • بشكل عام تقليل وقت الاختبار.


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



  • شكل الحقول والمعلمات ؛
  • صحة رموز الحالة ورسائل الخطأ ؛
  • الحقول المطلوبة ومنطق الخدمة.






اللحظة الحاسمة



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



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



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


لذلك ، قررنا تغيير نهج الاختبار وصياغة المتطلبات التالية للأدوات الجديدة:



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




ما علاقة Kotlin بها



تلبي لغة Kotlin احتياجاتنا قدر الإمكان.







بالإضافة إلى التوافق التام مع Java في Kotlin ، كنا مهتمين بالميزات التالية:



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


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



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



من الأقوال إلى الأفعال



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



في Kotlin ، يمكنك تهيئة كائن طلب بسطر واحد من التعليمات البرمجية. على سبيل المثال ، تبدو فئة ApplicationDTO (لإرسال استبيان إلى الحل) و ErrorDTO (الأخطاء القادمة من الخدمة) كما يلي:







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



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



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



دعنا نوضح بمثال بسيط على التحقق من الأخطاء لتسجيل دخول غير صحيح:



class ApplicationTests {

    val DEFAULT_LOGIN = "consLogin"
    val ERROR_CODE = "3"
    val BASE_URI = "https://base_url.com"

    @Test
    fun incorrectLogin() {
        val incorrectLogin = DEFAULT_LOGIN + "INCORRECT";
        val res = given()
                .spec(spec)
                .body(ApplicationDTO)
                .`when`()
                .post(endpointApplication(incorrectLogin)
                        .then()
                        .statusCode(400)
                        .extract().`as`(ErrorDTO::class.java)
                        assertThat(res.error_message).containsIgnoringCase("    ")
                        assertThat(res.error_code).isEqualToIgnoringCase(ERROR_CODE)
    }

    companion object{
        private var spec: RequestSpecification? = null

        @JvmStatic
        @BeforeClass
        fun initSpec() {
            spec = RequestSpecBuilder()
                    .setContentType(ContentType.JSON)
                    .setBaseUri(BASE_URI)
                    .addFilter(ResponseLoggingFilter())
                    .addFilter(RequestLoggingFilter())
                    .build()
        }
    }
}


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







مع Kotlin ، نخفض بشكل كبير كمية التعليمات البرمجية ، مما يعني أننا نجعل الحياة أسهل لكل من "الكتاب" و "القراء". تحتوي فئة ApplicationDTO بالفعل على مُنشئ وبعض الطرق الأخرى (hashCode () ، ونسخ () ، وما إلى ذلك) - لسنا بحاجة إلى "تحميل" التعليمات البرمجية معهم ولا يشتت انتباه مطوري الاختبار التلقائي المبتدئين. لا يلزم تحديثها في حالة حدوث أي تغييرات ، مما يقلل من وقت إجراء تعديلات على الاختبارات.



من الملائم أيضًا أن Kotlin يدعم الحجج المسماة - الرمز سهل القراءة تمامًا ، وليس هناك حاجة لكتابة مجموعات محددة لفئات كائن json بنفسك.



جرب أشياء جديدة مجانا



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



في المستقبل ، نخطط لتطوير نهج جديد وتوسيع نطاقه ليشمل مشاريع أخرى ، وترجمة بقية واجهات برمجة التطبيقات واختبارات واجهة المستخدم إلى Kotlin.



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



All Articles