-
Notifications
You must be signed in to change notification settings - Fork 90
Mobile tests with Appium
The project Beagle tests is a repository that contains user interface (UI) tests on mobile apps that use Beagle. These tests are implemented using Appium and Cucumber frameworks. This wiki shows how to run the mobile tests inside the repo Beagle tests.
- A mobile emulator (Android or iOS) must be running.
- The Appium server must be running at http://0.0.0.0:4723. Check this guide to install Appium. Driver-specific configuration is not needed. The focus is to install and run the server.
- A backend server that provides JSONs must be running. Refer to folder bff-server to run the server
- Android SDK and tools. Variable ANDROID_SDK_ROOT must be configured
- Load the Android emulator with Beagle's Appium Android app project. Once the app is installed, use the following command to open the emulator without opening Android Studio:
$ANDROID_SDK_ROOT/emulator/emulator -avd DEVICE-NAME
, whereDEVICE-NAME
is something likePixel_3a_API_30_x86
.
- Xcode and tools
- Generate the
AppiumApp.app
file by building the Beagle's Appium iOS app project. The .app file usually is located at~/Library/Developer/Xcode/DerivedData/{APP-RANDOM-CODE}/Build/Products/Debug-iphonesimulator/
Debugging is possible running Cucumber as a JUnit runner. This method is recommended to avoid breakpoint skipping problems during debugging a Gradle task. Follow the steps for running \ debugging through IDEA IntelliJ:
- Refer to class
br.com.zup.beagle.cucumber.steps.Runner.kt
in project./appium/project
as the official runner. - Right click on it and select "Run Runner" (using IntelliJ IDEA). This first run will fail because some parameters are missing.
- Edit the run plan and, under the Gradle section, add the following to the 'Arguments' field:
-Dplatform=android
(or ios).
Additional params must also be informed:
Android:
-Dplatform_version="11.0" -Ddevice_name="Google Pixel 4"
iOS:
-Dplatform_version="13.5" -Ddevice_name="iPhone 11" -Dapp_file="FULL PATH TO THE .app FILE"
Now, run \ debug the plan again.
To run all tests, use the tag of the mobile platform. For example, to run all Android tests use the following tags
@android and not @inProgress
in Runner.kt
class
To compile and run the whole test suite without using IntelliJ, under project ./appium/project
, execute the following command for Android:
gradlew cucumber -Dplatform="android" -Dplatform_version="11.0" -Ddevice_name="Google Pixel 4"
and for iOS:
gradlew cucumber -Dplatform_version="13.5" -Ddevice_name="iPhone 11" -Dapp_file="FULL PATH TO THE .app FILE"
Note that some params can be changed, for example device name. That will depend on the local emulator / simulator configuration.
Whenever a feature or step fails, the test suite will take a screenshot of the emulator and place it
in build/screenshots
folder under project ./appium/project
. This folder is always cleaned at the project execution start-up
Features (*.feature files) are located at src/test/resources/features
under project ./appium/project
.
For now, it is mandatory that they declare the @android
and @ios
tags. If a feature is not completed yet, it should be
tagged as in progress (@inProgress tag)
All step implementations must extend the AbstractStep.kt
class (project ./appium/project
) because of framework reasons.
This abstract class provides business logic methods to find and manipulate elements on screen. In general, these methods allow:
- Searching elements by its name, text or id
- Searching elements by its name or text with a like-search flag
- Searching elements by its name or text with a case-sensitivity flag
- Clicking on elements
- Sending value to text elements
- Swiping \ scroll the screen
- Taking screenshots
- Telling if an element is visible and clickable
- Telling if an element is visible and disabled
- Telling if an element is not present on the screen
Some tests rely on comparing the current app screen (screenshot) with reference images to identify if there are layout
or style changes. The following steps describe how to implement such tests in project ./appium/project
:
- Register a reference image by calling the method
registerCurrentScreenInDatabase("IMAGE-NAME")
inside a step implementation class. After the image was successfully registered in thescreenshots-database
folder, remove the method from the step implementation class. - In the step that is responsible to compare the current screenshot with the registered image, call the method
Assert.assertTrue(compareCurrentScreenWithDatabase('IMAGE-NAME'))
.
The most used utils class in the project ./appium/project
is AppiumUtil
since it concentrates all the Appium operations.
ImageUtil
is another important class as it takes care of image comparison. These util classes must not have business logic
code since they work as a lib and in the future might be exported as such.
There are several ways to find an element
with Appium. It's always recommended to search by a unique identifier, for example the element's Id (ex driver.findElementById(...)
).
However, and in most cases, there's no such unique identifier, and it is necessary to rely on other attributes to find
an element.
A reliable method to find elements, regardless of the mobile platform, is Xpath. Xpath relies on expression notation to search for elements by its attributes (id, name, class, etc), children or by other elements next to it. When choosing Xpath on mobile, notice that some element attributes have different names on each platform:
Element Attribute description | Android | iOS |
---|---|---|
Value (value of textfields, textareas, etc) | @text | @value |
Title (value of labels, tabs, buttons, etc) | @text | @name |
Class. Tells the type of element (image, button, etc) | @class | @type |
Id, a native element identifier | @resource-id | @name |
Accessibility id | @content-desc | @accessibility-id |
It's recommended to use Appium Inspector Tool on each platform to make sure the desired attribute is showing and set with the expected value. Basically, all the attributes shown in this tool will be accessible by Appium using Xpath.
Notice: Xpath has some drawbacks. The most notable is the long speed lookup, which affects specially iOS. For this reason, the tests use native iOS locators, such as such as Predicate or Class Chain.
Currently, Appium does not support the following operations:
- get an element's color and font properties (except for Webviews)
- get an element's alignment (LEFT, CENTER etc)
- tell if the keyboard is numeric (eg it will type letter keys even if the field is numeric only)
- restart or reset an Android activity
Most of the above operations are natively supported in other test frameworks like Espresso, however Espresso and Appium have different approaches and application scope. Appium for instance will test the app in a Black Box fashion, not having access to the app source code. Appium simulates a real user testing the app. Espresso on the other hand is a White Box test framework because it runs and has access to the app source code. Espresso only works with Android platform.
All these limitations, however, can be solved by screenshot testing.