-
Notifications
You must be signed in to change notification settings - Fork 89
Mobile tests with Appium
Beagle implements mobile user interface tests using Appium and Cucumber. The Appium tests project (./tests/appium/project
) implements single test cases that work for both Android and iOS. In other words, a single project tests both platforms.
- Emulator (Android or iOS) must be running
- Appium server must be running at http://0.0.0.0:4723. Check this guide to install the server. Driver-specific configuration is not needed. The focus here is to install and run the server.
- BFF must be running:
cd ./backend && gradlew bootRun -p automated-tests
- Device name or app location should be set in
SuiteSetup.kt
class, located in./tests/appium/project
project
- Android SDK and tools. Variable ANDROID_SDK_ROOT must be configured
- Load the Android emulator with Beagle's Appium Android app project (
./tests/appium/app-android
). 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 (./tests/appium/app-ios
). The .app file usually is located at~/Library/Developer/Xcode/DerivedData/{APP-RANDOM-CODE}/Build/Products/Debug-iphonesimulator/
- In
SuiteSetup.kt
class (project./tests/appium/project
), refer to the .app file path in theMobileCapabilityType.APP
capability under iOS section
To compile and run the whole test suite, under project ./tests/appium/project
execute the command gradlew cucumber -Dplatform=android
(or ios)
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./tests/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).
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
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 ./tests/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 ./tests/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 ./tests/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 ./tests/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 ./tests/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 its drawbacks too. The most notable is the long speed lookup, which affects specially iOS. For this reason, Beagle Appium 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.