First steps with AirtestIDE

This chapter introduces the key concepts of AirtestIDE and provides the very first steps how to work with AirtestIDE mainly for users who do not have many experiences with mobile apps and game testing.

Step 0: Before you start

What platforms can I run AirtestIDE on?

AirtestIDE is a cross-platform IDE that runs on Windows (x64) and macOS. For detailed instruction how to install AirtestIDE, see the instructions for Windows and macOS.

What do I need to do to before connecting the mobile device?

In order to be able to a use mobile device for testing and debugging mobile apps and games, the device needs to be in developer mode and USB debugging settings turned on.

If the used operating system is Windows OS, it might be needed to install corresponding device drivers on the system as well.

Step 1: Connecting device with AirtestIDE

When connecting the device to AirtestIDE, make sure that Device Window is selected in Window menu.

_images/device_window.png

There is the Mobile Phone Connection section on the right side of AirtestIDE GUI layout.

_images/mobile_phone_conn.png

Once the mobile device is connected, click Refresh ADB button to display the connected phones in the devices list table. If the status says Unauthorized, double check that the USB debugging is enabled and the computer is allowed to perform USB debugging on the device.

If the mobile device still does not appear in the devices list, try to click Restart ADB and then Refresh ADB again. If the difficulties persist, perform following steps:

macOS:

$ adb devices
List of devices attached
FA69J0305903    device
0a33789f        device

Windows OS:

  1. locate the adb executable, the default path is: AirtestIDE\airtest\core\android\static\adb\windows\adb.exe
  2. run adb.exe devices and check if devices can be properly listed

If the device is listed when executing command above but it does not appear in the IDE, feel free to contact us and report the problem.

Click Connect button next to the device you want to connect, the content of the device screen will appear. If the device is locked, it can be unlocked either directly using device buttons, or you can start to operate the device using the IDE - e.g. click Power button below the screen to wake up the device and use the mouse to unlock the device.

_images/device_screen.png

Step 2: Look around

Let’s have a look at the IDE windows layout. On the top, there is a menu bar and shortcut buttons for creating a new project, saving project, run script and check the report output.

The upper left side contains the Poco Window that assists you to work with UI elements of the selected interface and where you can see the selected UI interface in the tree structure form.

The bottom left side contains the Airtest Window that provides commonly used statements for assisting to capture the recording of the Airtest scripts (based on image recognition techniques).

The central area contains the scripting section for developing own scripts in Python using Poco and Airtest APIs. The log output section below displays the corresponding log content while executing the script.

On the right side, there is a mobile phone screen in real-time with support to use mouse events for remote control of the device.

_images/airtest_ui.png

Step 3: Write your first test scenario

For easier understanding how AirtestIDE works, let’s assume the app you want to test is already installed on the mobile device. For demonstration purposes and first test scenario, we use Google calculator app and we check if it works properly by doing some actions in it.

We write the script directly inside the IDE under the line # start your script here (see the red section 1 in the screenshot below).

_images/airtest_ide_first_script.png

Launch the app to test

To start executing the script, click the play button in the top left area (see the blue section 3 in the screenshot above) or add following lines directly into your test script:

start_app("package_name")
start_app("com.google.android.calculator")

Function start_app("package_name") is an api provided by Airtest package, please refer to documentation for more details.

Simulate click on some UI elements

For simulating the click on UI elements, we will Use the Poco framework which understands the Android UI elements and is also responsible for simulating the inputs. To do so, change the mode of the Poco framework to Android as shown in the following screenshot.

Note

As you can see, you can combine the Airtest APIs with Poco APIs without any restrictions

_images/change_to_android.png

After doing that you will be prompted to answer the yellow message in the script area: “Poco mode has changed. Do you want to insert poco init code at the current cursor position?”.

_images/poco_init_code_prompt.png

Answer Yes to add Poco init code to the line where your cursor is. At the same time, Poco framework determines the UI hierarchy and draws it in a tree structure (see the yellow section 2 in the screenshot above)

_images/poco_init_code.png

All the input can be automatically captured, click on “Poco auto recording” to enable auto recording. Now, click on the element you want to interact with on the phone screen in the IDE. You can see the currently selected button is being highlighted and when you click on it, it will add code to your script.

_images/poco_auto_recording.png

At any point, you can click the “Poco auto recording” button again to stop capturing the actions and play the script to see how it performs the actions in real life by pressing “Play” button.

Make some asserts

In steps above we have created a simple script that counts 7 + 3 in Google calculator app, now we can add an assert to make sure that the calculator displays the result properly.

# -*- encoding=utf8 -*-
__author__ = "kristyna"
__title__ = "little bit fun with calculator"
__desc__ = """having little bit fun with Google calculator basic functionalities"""

# start the app
start_app("com.google.android.calculator")

# poco init code
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(force_restart=False)

# simple math 7+3 = 10
poco("com.google.android.calculator:id/digit_7").click()
poco("com.google.android.calculator:id/op_add").click()
poco("com.google.android.calculator:id/digit_3").click()
poco("com.google.android.calculator:id/eq").click()

First we need to identify where the result is displayed. For instance you can just simulate a click on the result to your script as follows:

poco("com.google.android.calculator:id/result").click()

But in real life we do not want to click on result, we just want to get the value of the result, so instead of click action we can use get_text() action and assign the value to variable:

res = poco("com.google.android.calculator:id/result").get_text()

And finally, we can make the assert:

# make an assert
assert_equal(res, "10", "simple math")

For demonstration purposes, we can create assert that fails:

# this assert will fail
assert_equal(res, "0", "this assert fails")

Check the output of the script and the results

Run the script using play button and wait for it to complete. Once it finishes, click on the Log button as shown on screenshot below.

_images/check_log.png

It will open the browser with the report what happened during the test. The test report includes one screenshot for each action that was simulated including the information if the step was performed succesfully or not. You can also see the assert result.

_images/test_report_1.png _images/test_report_2.png

We can reach the same result with Airtest framework, however, the Airtest framework uses the different approach. Airtest framework works on image recognition techniques, so we have to create the image templates first as follows:

  1. in Airtest assistant window click the corresponding method button - touch in our case
  2. move the mouse to the device screen and draw a rectangle around the object of interest
  3. repeat the previous step until you select all desired objects
  4. to check the result, we will create an assertion - use the assert_exists function
  5. to run or replay the scenario, click Run button or F5 key shortcut
  6. after the script finishes, you can see the report by pressing Log button as described above.
_images/airtest_script_sample.png

Apendix

Poco script example

This is a calculator script with swipe, long press and several asserts actions.

# -*- encoding=utf8 -*-
__author__ = "kristyna"
__title__ = "little bit fun with calculator"
__desc__ = """
having little bit fun with Google calculator
basic functions
"""

# poco init
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(force_restart=False)

# start Google calculator
start_app("com.google.android.calculator")

# make sure the initial state is clear
if poco("com.google.android.calculator:id/clr").exists():
    poco("com.google.android.calculator:id/clr").click()
else:
    val = poco("com.google.android.calculator:id/formula").get_text()
    print("formula val")
    print(val)
    while val is not None:
        poco("com.google.android.calculator:id/del").long_click()
        val = poco("com.google.android.calculator:id/formula").get_text()

# make side panel appear by clicking
assert(not poco("com.google.android.calculator:id/op_pct").exists())
poco("com.google.android.calculator:id/arrow").click()
assert(poco("com.google.android.calculator:id/op_pct").exists())

# and then make the side panel disapear by swiping
poco("com.google.android.calculator:id/arrow").swipe([0.5, 0.0])
#Quick fix for the swipe issue
#poco("com.google.android.calculator:id/digit_7").click()
assert(not poco("com.google.android.calculator:id/op_pct").exists())

# test the delete key short press
poco("com.google.android.calculator:id/digit_7").click()
poco("com.google.android.calculator:id/digit_3").click()
assert_equal(poco("com.google.android.calculator:id/formula").get_text(), "73",
             "Enter 73 operand")
poco("com.google.android.calculator:id/del").click()
poco("com.google.android.calculator:id/del").click()
assert_equal(poco("com.google.android.calculator:id/formula").get_text(), None,
             "Delete operant short press")

# simple multiplication
poco("com.google.android.calculator:id/digit_5").click()
poco("com.google.android.calculator:id/digit_6").click()
poco("com.google.android.calculator:id/op_mul").click()
poco("com.google.android.calculator:id/digit_4").click()
poco("com.google.android.calculator:id/eq").click()
val = poco("com.google.android.calculator:id/result").get_text()
assert_equal(val, "224", "simple multiplication")
poco("com.google.android.calculator:id/clr").click()

# simple addition
poco("com.google.android.calculator:id/digit_2").click()
poco("com.google.android.calculator:id/op_add").click()
poco("com.google.android.calculator:id/digit_2").click()
poco("com.google.android.calculator:id/eq").click()
val = poco("com.google.android.calculator:id/result").get_text()
assert_equal(val, "4", "simple addition")
poco("com.google.android.calculator:id/clr").click()

# chaining operations
poco("com.google.android.calculator:id/digit_2").click()
poco("com.google.android.calculator:id/op_mul").click()
poco("com.google.android.calculator:id/digit_9").click()
poco("com.google.android.calculator:id/eq").click()
poco("com.google.android.calculator:id/op_add").click()
poco("com.google.android.calculator:id/digit_6").click()
poco("com.google.android.calculator:id/eq").click()
val = poco("com.google.android.calculator:id/result").get_text()
assert_equal(val, "24", "Chaining simple operations")
poco("com.google.android.calculator:id/clr").click()

poco("com.google.android.calculator:id/pad_advanced").click()
poco("com.google.android.calculator:id/fun_sin").click()
poco("com.google.android.calculator:id/digit_1").click()
poco("com.google.android.calculator:id/digit_5").click()
poco("com.google.android.calculator:id/eq").click()
val = poco("com.google.android.calculator:id/result").get_text()
assert(float(val) < 0, "Sinus is not working")
_images/poco_example_animated.gif

Airtest script example

This is a calculator script to count 7 + 3 = 10 with the assertion to check the result. The script contains the reference to screenshot templates created during the script recording and these screenshots are part of .air project directory:

enceladus:airtest-ide kristyna$ ls -lrt airtest_script.air/
total 80
-rw-r--r--  1 kristyna  staff   2929 Feb  9 11:00 tpl1518145202547.png
-rw-r--r--  1 kristyna  staff   2130 Feb  9 11:00 tpl1518145254032.png
-rw-r--r--  1 kristyna  staff   4794 Feb  9 11:01 tpl1518145262292.png
-rw-r--r--  1 kristyna  staff   1074 Feb  9 11:01 tpl1518145267964.png
-rw-r--r--  1 kristyna  staff  14009 Feb  9 11:01 tpl1518145311495.png
-rw-r--r--  1 kristyna  staff    670 Feb  9 11:25 airtest_script.py
# -*- encoding=utf8 -*-
__author__ = "kristyna"
__title__ = "fun with Airtest and Google calc"
__desc__ = """
let's play with Google calc a bit
"""

# start your script here
touch(Template(r"tpl1518145202547.png", record_pos=(-0.375, 0.203), resolution=(1200, 1824)))
touch(Template(r"tpl1518145254032.png", record_pos=(0.247, 0.662), resolution=(1200, 1824)))
touch(Template(r"tpl1518145262292.png", record_pos=(0.032, 0.507), resolution=(1200, 1824)))
touch(Template(r"tpl1518145267964.png", record_pos=(0.407, 0.653), resolution=(1200, 1824)))
assert_exists(Template(r"tpl1518145311495.png", record_pos=(0.361, -0.494),
                       resolution=(1200, 1824)), "simple math")






_images/airtest_script_animated.gif