كيفية كتابة اختبارات Android UI

مرحبا. نحن في Avokado Project نواصل الحديث عن الاختبار التلقائي في Android. هذه المقالة هي نظرة عامة ومقارنة للأدوات الموجودة لكتابة اختبارات واجهة المستخدم.



لنبدأ بالتذكير بالشكل الذي تبدو عليه عادة عملية الاختبار. دعنا نسمي الكيان الذي يتفاعل مع التطبيق العميل. للتفاعل مع التطبيق ، عادة ما يكون لدى العميل العديد من الواجهات المتاحة: API ، REST API ، CLI ، GUI ، إلخ. وإذا تم ، على سبيل المثال ، استخدام واجهات برمجة التطبيقات بواسطة برامج العملاء ، فسيتم استخدام واجهة المستخدم الرسومية من قبل البشر.



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





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



  - . ,   .     -.



(JUnit, Cucumber).  :



  • — (assertions).
  •    .    — ,   .
  •   .


  :



  • ;
  •  ;
  • ;
  • ;
  •   ;
  • .


,   , . ,   Android-, (Avito test runner, Marathon, Spoon, Fork) ,   .



API ,  GUI  — .





,  GUI-, UI-.    unit-,     .



GUI- . , . GUI- (Espresso, UiAutomator) «  », ,  ,    .



API   :



  • :   , , , .
  • API .
  •   .


, , Kakao Kaspresso.     .   — ,  — , .





  ,  .





Android- :



  • Espresso.
  • UiAutomator.
  • Robotium.
  • Selendroid.


 Android Instrumentation Framework — API Android    .  — Espresso UiAutomator. Google.   . .



UiAutomator





UiAutomator  Android SDK  16 API. GUI-     : , , , , .   ,    — Ui Automator Viewer.



UiAutomator   (black-box).       . ,     ,   .   , , :



  • ;
  • ;
  • ;
  • , ;
  • .


UiAutomator   AccessibilityService,     . AccessibilityService ,       .   ,   AccessibilityNodeInfo.   View: , .





View AccessibilityEventSource Binder IPC AccessibilityManagerService   ,  , ,   . AccessibilityManagerService     AccessibilityService ,   , UiAutomator, .      AccessibilityService’ UiAutomator’a    . View,       .



  UiAutomator   “UI Automator deep diving”.



UiAutomator:



  • , Binder IPC, .  , UiAutomator ,   . ,     .   ,     .
  • , View   OpenGL Unity,  UiAutomator’a,   . , ,      UiAutomator’a .


,   UiAutomator   ,   .     Espresso.



Espresso





 UI-  Google,     (white-box). Espresso Android API  10 , .   .



Espresso  .  ,    .



Espresso  —     (ViewMatcher),   (ViewAction) (ViewAssertion).





Espresso   Hamcrest.    — ,  ,   Espresso —   .    ,   , .  , .



@Test
public void espressoTest() {
    onView(allOf(allOf(withId(R.id.label_bf_hotelname), 
        isDescendantOfA(withId(R.id.custom_view_trip_review))), 
        isDescendantOfA(withId(R.id.contentView))))
        .check(matches(
            withEffectiveVisibility(Visibility.VISIBLE)
        ));
}


 Espresso  — Espresso   ,   .   .  ,   (idle).





,  ,  , , check ViewInteraction. ViewAssertion   idle’.



public ViewInteraction check(ViewAssertion viewAssertion) {
    // (...)
    runSynchronouslyOnUiThread(new Callable<Void>() {
        @Override
        public Void call() {
            uiController.loopMainThreadUntilIdle();
            // (...)
            viewAssertion.check(...)
        }
    });
}


  Espresso:



  •   .
  •     . , , .   Espresso .     UiAutomator.
  • API Espresso , .   .
  • Espresso        .


,   , Espresso — , .



Robotium Selendroid



Robotium Selendroid   Espresso UiAutomator. C , .   ,     .



Robotium    Android API 8+, (  WebView , ,  API 15),    Java. Robotium Recorder  IntelliJ IDEA Android Studio.



Selendroid API —  10  19. WebDriver, Inspector   record-and-playback-.



 , Robotium Selendroid.



Robolectric



 , Robolectric   , . ,   Android UI-. Robolectric unit-   JUnit Android API.



Android SDK, shadow-. Robolectric   , inflate view, , , -  Android-. Robolectric ,  Android,   ,   JVM. , .





,     . , :     - . -  API,   . ,     . ,     , ,  Espresso UiAutomator.



.  API   ,   .



, ,  .



.  UI-  ,   .     ( . , ).   ,   . .   , .



. ,   , ,   .     , ,   UI-.



.    ,   , .    black-box . . ,   , black-box , ,   .       white-box, black-box .



.   ,   . , . , ,     .



. , . : , , ,  —   ,  , . ,   , , ,     .   stacktrace’  , , , , .



. . ,     . ,   .



adb.    adb: / , ,     .



API.  — , .   , , ,  —   ,   .   ,   ,     .   ,  .



  .



Appium





Appium — - open source   Android iOS. Appium  Selenium WebDriver,  web-.     . Appium-  ,  .   Appium   API.





.  , Appium .   HTTP-  Node.JS, WebDriver-,    .  ,  ,   .   ,  , Appium .



. Appium  ,   . Android     UiAutomator,     Espresso.  ,  ,     . . Espresso UiAutomator.



API.   Appium   API,  WebDriver. Appium  ,   .



.   , ,   , , ( ),  Appium-, , , ,   .   , .  — .



.   , .



.   , .



adb. -  Appium’  ,   adb-. , , .



. Appium .  — Espresso . -   ,      .



, Appium — Android- . ,   Kotlin,    Java. -  Appium   . ,   .   : «  . , , », «  ».



Kakao





Kakao — Kotlin DSL  Espresso.  Espresso .



API.   Kakao —   boilerplate-     :



  • KView — Kakao-  ,     . , Kakao , KEditText, KButton .. .
  • Screen —   - PageObject. Screen — ,   stateless- KView   . Screen   , , , . Screen’   ,       .


, ,   Espresso. :



@Test
public void espressoTest() {
    onView(allOf(allOf(withId(R.id.label_bf_hotelname),
        isDescendantOfA(withId(R.id.custom_view_trip_review))),
        isDescendantOfA(withId(R.id.contentView))))
        .check(matches(
            withEffectiveVisibility(Visibility.VISIBLE)
        ));
}


:



object MainScreen : Screen<MainScreen>() {
    val hotelName = KTextView { withId(R.id.label_bf_hotelname) }
}

@Test
fun kakaoTest() {
    MainScreen { 
        hotelName { 
            isVisible() 
        } 
    }
}


. Kakao —  , Appium,     . - . Espresso  , ,  —   , ..



. Kakao Espresso,       .



.    Kakao .   API  , Espresso-.  , , . - - .



.   ,  Espresso.   .



.   . .



adb. ,  Espresso.



. , Kakao — DSL    Espresso.   UiAutomator, API .     , ,   .



Barista





Barista — ,    Espresso.



API. Kakao, Espresso. Barista — ,   Espresso-.  :



  • helper-     ,   Espresso . ,     onView(withId(R.id.button)).perform(click())   Espresso clickOn(R.id.button).     clickListItem(R.id.list, 4).
  • Android- Assertions API.
  •   ,  .
  •    runtime permission’.
  • test rule’, ,   flaky-     shared preferences, ,  .


Barista  NestedScrollView,    Espresso,   . DSL ,    .



. FlakyTestRule . .       , .



. -  Espresso.



.     ,   Espresso . Espresso.



. ,   .



. .



adb. ,  Espresso.



. Barista    .  ,      , .         .



Kaspresso





-  UI-,  ,        .



API.   Kakao. Kaspresso Kakao DSL — Kotlin DSL   , Kakao   Screen’ KView.



@RunWith(AndroidJUnit4::class)
class OpenHomeScreenTest : TestCase() {

    @Test
    fun kaspressoTest() {
        before { ... }
        .after { ... }
        .run {
            step("1. Open Home screen") { 
                MainScreen {
                    openHomeScreenBtn.click()
                }
            }
            step("2. Check Home title") { 
                HomeScreen {
                    title.isVisible()
                }
            }
            step("3. Do some stuff") { ... }
        }
    }
}


Kaspresso API   ,   .   , (. How to write autotests).



. Kaspresso -   API  Espresso  UiAutomator. ,   , , . ,      ,   . Kaspresso Kautomator — Kakao-like  UiAutomator,    Espresso  UiAutomator .



object KakaoScreen : Screen<KakaoScreen>() {
    val title = KTextView { withText(titleText) }
    val btn = KButton { withId(R.id.button1) }
}

object KautomatorScreen : UiScreen<KautomatorScreen>() {
    val title = UiTextView { withText(titleText) }
    val btn = UiButton { withId(pkgName, R.id.button2) }
}

@Test
fun kaspressoTest() {
    KakaoScreen { 
        title.isVisible()
        btn.click()
    }
    KautomatorScreen {
        title.isVisible()
        btn.click()
    }
}


  device. ,   :



  • ;
  • ;
  •   ;
  • , , ;
  •   ;
  • ;
  • ;
  •   : back, home, recents.


Kaspresso   , .



. Kaspresso , .     , ,   ViewAction ViewAssertion,  , . ,   , , (. Configurator).



. Kaspresso   Espresso UiAutomator , ,   ScrollView, , . helper-. ,       flakySafely:



MainScreen {
    flakySafely {
        btn.click()
    }
}


.   ,   , .



.       . , Kaspresso , .   :



device.screenshots.take("MainScreen_step_1")


. Localization autotests.



adb. Kaspresso AdbServer — HTTP-,   adb-.  ,   ,   .      ,   adb-   . AdbServer   ,   device. API   adb-:



adbServer.performAdb("emu sms send +79111111111 $smsText")
adbServer.perfromShell("rm -f $filePath")


AdbServer , ,    adb.





Appium Kakao Barista Kaspresso
API + ± +
+ +
+ +
± ± +
± +
+
adb + +
من هذا الجدول ، يجب أن تكون الإجابة واضحة. إذا كنت قد بدأت للتو في الغوص في عالم الاختبار التلقائي ، فإن أسهل مكان للبدء هو Kaspresso. سوف يحل لك العديد من المشاكل التي ستواجهها بالتأكيد. يوفر واجهة برمجة تطبيقات ملائمة تتضمن Kakao وتوسعها ، والتي تخفي المكالمات إلى Espresso و UiAutomator و AdbServer ، مما يوسع قدراتك بشكل كبير. أخيرًا وليس آخرًا ، يحتوي على نقاط امتداد خاصة حتى تتمكن من الحصول على السلوك الذي تريده منه.



All Articles