Skip to main content
Espresso Automation Framework
Doris Sooläte avatar
Written by Doris Sooläte
Updated over 11 months ago

Espresso automation framework meant to replicate MVVM pattern (https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel), where framework is compotentized in

  • Helpers(for locators interaction)

  • Screens (containing the locators with other methods)

  • Test scripts (performing and validating the e2e flow)

Tools needed to be installed on the machine

  1. Java 11 (Other version of Java might not work)

  2. Maven

  3. Android Studio

Setup Steps

  • Clone the Espresso branch from repo

  • Open the project in Android studio

  • Open the terminal

  • Run command `./gradlew build`

  • It will take some time to install all dependencies, based on your network bandwidth and processing power

  • To run all UI tests use command `./gradlew connectedAndroidTest`

Understanding framework components

  • After building the framework here our automation project lies within source folder(Marked in red)

  • Select Tests view from the red bordered drop, Now we can see our tests

  • Now this `automation` package contains our Espresso based framework

  • In `tests` package, we are having all our UI tests

  • We have BaseTest class to setup the `Before` hook, to clean DB

  • All UI test classes inherit this class

  • The `screens` package contains all Screen class replicating each screen of the app. Screen class initializes all helper class, which can be used in derived screen class or test

  • The Helper package contains helper classes to provide method to deal with UI, DB and other utilities

  • The `annotations` package to create custom annotation for the test

Getting locators (In Espresso terms, views)

Android Studio has a inbuilt tool, Layout Manager for detecting view on app layout

  • Working with Layout Manager - got to the Tools menu and click the `Layout Manager` menu item. Start an emulator and open the debuggable app for which you want to capture views

  • On one side of layout manager component can be observed while other side we can view properties

  • Now, here is the cheat sheet using we can create view matcher (please see user properties) from the properties of the view https://developer.android.com/training/testing/espresso/cheat-sheet

Writing Screen classes -

Any screen will inherit Screen class, so that Locator, Action and Validators becomes available to them and it has two essential parts described below

  • Label property object, which will be formatted as

    companion object {
    // Labels locator
    const val EXPANDED_VIEW_BUTTON_TEXT = "Expanded View - ButtonText"
    const val REDUCED_VIEW_BUTTON_TEXT = "Reduced View - ButtonText"
    const val LEFT_MENU_BUTTON = "Left Menu - Button"
    }
  • The label vale format should be “<App identifier view name> - <Type of view>”

  • Two component with initializing the label map

    init {
    locators.put(EXPANDED_VIEW_BUTTON_TEXT,
    Locator(EXPANDED_VIEW_BUTTON_TEXT,
    ViewMatchers.withText(R.string.expanded_view)))
    locators.put(REDUCED_VIEW_BUTTON_TEXT,
    Locator(REDUCED_VIEW_BUTTON_TEXT,
    ViewMatchers.withText(R.string.contracted_view)))
    locators[LEFT_MENU_BUTTON] = Locator(LEFT_MENU_BUTTON,
    Matchers.allOf(ViewMatchers.withContentDescription("drawer open"),
    ViewHelper.getChildAtPosition(Matchers.allOf(ViewMatchers.
    withId(R.id.toolbar),
    ViewHelper.getChildAtPosition(ViewMatchers.withClassName
    (Matchers.`is`("android.widget.RelativeLayout")), 0)), 1), ViewMatchers.isDisplayed()))
    }
  • Where we are adding new entries in `locator` map

  • Locator map use `Label` as key view as key value

Now we can define page object methods in page class

private fun openDrawer() {
Action.perform(LEFT_MENU_BUTTON)
}

Writing the Test script

Test script would be automated steps to replicate the manual test case and feature, Every Test class will be inheriting Basetest

Example class -

class NotesListTest : BaseTest() {
@Test
fun switchExpandedCollapsedNoteLayoutTest() {
sharedPreferences?.edit()?.putBoolean(Constants.PREF_EXPANDED_
VIEW, true)?.apply()
createNote()
noteListView?.Menu?.clickOverflowMenuButton()
noteListView?.Menu?.Validator?.validate("Reducedview",
StateType.DISPLAYED)
noteListView?.Menu?.Action?.perform(NoteListMenuViewScreen.
REDUCED_VIEW_BUTTON_TEXT)
noteListView?.Menu?.clickOverflowMenuButton()
noteListView?.Menu?.Validator?.validate("Expanded view"
, StateType.DISPLAYED)
}
}

Validate will be done via Validator class methods

Execution -

  • To run all connected android test use `./gradlew connectedAndroidTest`

  • To run one test class `./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=<Class-Reference>`

  • You can also, mark your tests with annotations, `./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.annotation=<path-to-annotation>

Did this answer your question?